Submission #763917

#TimeUsernameProblemLanguageResultExecution timeMemory
763917hanluluMecho (IOI09_mecho)C++14
100 / 100
161 ms6172 KiB
//https://cses.fi/problemset/task/1707
#include <bits/stdc++.h>
using namespace std; 
/*
有点像793的题目,两次最短。Bee走出到每一个位置的最短,
然后二分答案,然后Mecho走最短的时侯每一个相邻是否可以走需要计算是否Bee先到。
如何处理一分钟走s步这里?dis记录当前的步数,每次走到相邻+1,但是时间可以用dis/s得到。
注意:一个位置如果bee先到,比如2s到,m 3s到,那么m就不能走,如果相等可以走,因为每一次都是m先走。
但是,终点要特殊处理。 能到达终点的周围四个点就可以到达。 
*/
int n,s;
char a[801][801];
int rdir[4] = {0,0,1,-1};
int cdir[4] = {1,-1,0,0};
vector<vector<int>> beetime(801,vector<int>(801,1e9));

int sx,sy,ex,ey;//起点和终点 

bool isok(int eat)//eat is how many time he stay at start point. 
{
	if (eat >= beetime[sx][sy]) return false;
	vector<vector<int>> mstep(801,vector<int>(801,1e9));
	//cout << eat << endl;
	queue<pair<int,int>> myq;
	mstep[sx][sy] = 0;
	myq.push({sx,sy}); 
	while (!myq.empty()) {
		int x = myq.front().first;
		int y = myq.front().second;
		myq.pop();
		for (int i = 0; i < 4; i++)
		{
			int newx = x + rdir[i];
			int newy = y + cdir[i];
			if (a[newx][newy] == 'D') return true;//终点不需要判断了。因为bee到不了。 
			if (newx <0 || newx == n || newy < 0 || newy == n) continue;
			if (a[newx][newy] == 'T' || a[newx][newy] == 'H' ) continue;
			if (mstep[newx][newy] <= mstep[x][y] + 1) continue;
			//if (beetime[newx][newy] < ceil(1.0*(mstep[x][y]+1) /s) + eat) continue; 
			if (beetime[newx][newy] <= (mstep[x][y]+1) /s + eat) continue; 
			//cout << newx << " " << newy << " " << (mstep[x][y]+1) /s + eat << endl;
			mstep[newx][newy] = mstep[x][y] + 1;
			
			myq.push({newx,newy});
		}		
	}
	//cout <<  mstep[2][2]  << endl;
	return false;
}
int main()
{
  	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	//freopen("nocross.in","r",stdin);
	//freopen("nocross.out","w",stdout);
 	cin >> n >> s;
	
	queue<pair<int,int>> myq;
 	for (int i = 0; i < n; i++) 
 	for (int j = 0; j < n; j++) 
 	{
 		cin >> a[i][j];
 		if (a[i][j] == 'M') sx = i, sy = j;
 		if (a[i][j] == 'D') ex = i, ey = j;
 		if (a[i][j] == 'H') {
 			beetime[i][j] = 0;
 			myq.push({i,j});
		};
	}	

  	//find beetime
	while (!myq.empty()) {
		int x = myq.front().first;
		int y = myq.front().second;
		myq.pop();
		for (int i = 0; i < 4; i++)
		{
			int newx = x + rdir[i];
			int newy = y + cdir[i];
			if (newx <0 || newx == n || newy < 0 || newy == n) continue;
			if (a[newx][newy] == 'T' ||  a[newx][newy] == 'H' ||  a[newx][newy] == 'D') continue;
			if (beetime[newx][newy] <= beetime[x][y] + 1) continue;
			
			beetime[newx][newy] = beetime[x][y] + 1;			
			myq.push({newx,newy});
		}
	}
	  //	cout << beetime[2][2]<< endl;
  	//bin the answer
  	int ans = -1;
  	int l = 0, r =  n*n, mid;
  	while (l <= r) {
  		mid = (l+r)/2;
  		//cout << "mid " << mid <<  endl;
		if (isok(mid)) {
			ans = mid;
			l = mid + 1;
		}	
		else r = mid - 1;
	}
	cout << ans << '\n'; 
	return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...