[problem solving] 70 points of driving trip (doubled dfs simulation) of day 1 T3 in NOIP2012 improvement group

Posted by baldwinw on Thu, 09 Jan 2020 19:30:25 +0100

This article is from: Original address

Multiplication is not learned, but we can get 70 points by simulation and dfs.

The handwritten dis function calculates the absolute value of the distance between two cities = the altitude difference. Let's set a two-dimensional array of km[i][2] to record the nearest and the second nearest city to I city. There are many details in the title. For example, when the distance is the same, it is judged that the city with low altitude is closer. Let m2 m1 be 0 to represent the nearest city to I, circular city I, recycling J (i+1 to n). If the above conditions are met, update M1 with J and m2 with M1. Of course, there is a case where j is not the latest but can update the next closest. Just use if. Enter x0. First, let's find out which city to start from when the total distance does not exceed x0, and the ratio of driving distance between a and B is the smallest. It can be simulated by four parameters transmitted by dfs, s represents the number of the starting city, X represents whether the small a or B has driven (stored in the previous km array), da and db represent the driving distance of the small a and B respectively. If there is no legal city in front of the current city or the sum of the distances between da, db, s and to is greater than x0, it will stop. Otherwise, when the input parameter is equal to 2, it means that small a drives, da+=dis (s, to). dfs starts from to, and the input parameter is converted to another one. Using this dfs, we can enumerate cities to find their da and db values. If db==0 and the ratio is - 1 (representing positive infinity), then we should compare the elevation of the two cities. If the current city altitude is higher than the ans altitude, update ans. If db is not 0, if the ratio is - 1, then it will be updated. If the ratio is not - 1, if da/db (double type) < ratio or equal to ratio, and if the altitude is higher, then the first question can be obtained. For the second question, after reading the penalty city and the maximum limit, the output of da db can be obtained by using the dfs function

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
int n,m;
int h[100100];
int q,x0;
int km[100100][3];
int dis(int x,int y)
{
	if(x==0||y==0) return (2e9)+1;
	return abs(h[x]-h[y]);
}
void dfs(int s,int x,int &da,int &db)
{
	int to=km[s][x];
	if(to==0) return ;
	int d=dis(s,to);
	if(da+db+d>x0) return;
	if(x==1)
	{
		db+=d;
		dfs(to,2,da,db);
	}
	if(x==2)
	{
		da+=d;
		dfs(to,1,da,db);
	}
}

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&h[i]);
	}
	for(int i=1;i<=n;i++)
	{
		int m1=0,m2=0;
		for(int j=i+1;j<=n;j++)
		{
			if(dis(m1,i)>dis(j,i)||(dis(m1,i)==dis(j,i)&&h[j]<h[m1]))
			{
				m2=m1;
				m1=j;
			}
			else
			{
				if(dis(m2,i)>dis(j,i)||(dis(m2,i)==dis(j,i)&&h[j]<h[m2]))
				{
					m2=j;
				}
			}
		}
		km[i][1]=m1;
		km[i][2]=m2;
	}
	scanf("%d",&x0);
	int ans=0;
	double ra=-1; //Infinite ratio
	for(int i=1;i<=n;i++)
	{
		int da=0,db=0;
		dfs(i,2,da,db);
		if(db==0)
		{
			if(ra==-1&&h[i]>h[ans])
			{
				ans=i;
			}
		} 
		if(db!=0)
		{
			if(ra==-1||(1.0*da/db<ra||(1.0*da/db==ra&&h[i]>h[ans])))
			{
				ans=i;
				ra=1.0*da/db; 
			}
		}
	}
	cout<<ans<<endl;
	
	scanf("%d",&m);
	for(int i=1;i<=m;i++)
	{
		int si;
		scanf("%d%d",&si,&x0);
		int da=0,db=0;
		dfs(si,2,da,db);
		printf("%d %d\n",da,db);
	}
	
	//fclose(stdin);
	//fclose(stdout);
	return 0;
}