【分类讨论】【spfa】【BFS】Codeforces Round #416 (Div. 2) D. Vladik and Favorite Game

那个人第一步肯定要么能向下走,要么能向右走。于是一定可以判断出上下是否对调,或者左右是否对调。

然后他往这个方向再走一走就能发现一定可以再往旁边走,此时就可以判断出另一个方向是否对调。

都判断出来以后,跑个spfa或者bfs就行了。

细节较多……有一些边界情况需要处理。比如终点在第一行或者第一列的情况。

#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
typedef pair<int,int> Point;
Point ma[110*110*10];
const int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
int n,m,End;
char a[110][110];
int num[110][110],pen;
queue<int>Q;
int dis[110*110*10],v[110*110*4*10],e,__next[110*110*4*10],first[110*110*10];
int pre[110*110*10];
bool inq[110*110*10];
void AddEdge(int U,int V){
	v[++e]=V;
	__next[e]=first[U];
	first[U]=e;
}
void spfa(const int &s)
{
    memset(dis,0x7f,sizeof(dis));
    dis[s]=0; Q.push(s); inq[s]=1;
    while(!Q.empty())
      {
        int U=Q.front();
        for(int i=first[U];i;i=__next[i])
          if(dis[v[i]]>dis[U]+1)
            {
              dis[v[i]]=dis[U]+1;
              pre[v[i]]=U;
              if(!inq[v[i]])
                {
                  Q.push(v[i]);
                  inq[v[i]]=1;
                }
            }
        Q.pop(); inq[U]=0;
      }
}
Point path[110*110*10];
int p;
bool lr,ud;
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i){
		scanf("%s",a[i]+1);
	}
	for(int i=1;i<=n;++i){
		for(int j=1;j<=m;++j){
			num[i][j]=++pen;
			ma[pen]=make_pair(i,j);
			if(a[i][j]==‘F‘){
				End=num[i][j];
			}
		}
	}
	for(int i=1;i<=n;++i){
		for(int j=1;j<=m;++j)if(a[i][j]==‘.‘ || a[i][j]==‘F‘){
			for(int k=0;k<4;++k){
				int tx=i+dx[k],ty=j+dy[k];
				if(a[tx][ty]==‘.‘ || a[tx][ty]==‘F‘){
					AddEdge(num[i][j],num[tx][ty]);
				}
			}
		}
	}

	if(End==1){
		return 0;
	}
	int x,y;
	if((a[2][1]==‘*‘ || n==1) && (a[1][2]==‘.‘ || a[1][2]==‘F‘)){
		puts("R");
		fflush(stdout);
		scanf("%d%d",&x,&y);
		if(x==1 && y==1){
			lr=1;
		}
		while(a[x][y]!=‘F‘ && a[x+1][y]==‘*‘){
			puts(lr ? "L" : "R");
			fflush(stdout);
			scanf("%d%d",&x,&y);
		}
		if(a[x][y]==‘F‘){
			return 0;
		}
		puts("D");
		fflush(stdout);
		scanf("%d%d",&x,&y);
		if(a[x][y]==‘F‘){
			return 0;
		}
		if(x==1){
			ud=1;
		}
	}
	else if((a[1][2]==‘*‘ || m==1) && (a[2][1]==‘.‘ || a[2][1]==‘F‘)){
		puts("D");
		fflush(stdout);
		scanf("%d%d",&x,&y);
		if(x==1 && y==1){
			ud=1;
		}
		while(a[x][y]!=‘F‘ && a[x][y+1]==‘*‘){
			puts(ud ? "U" : "D");
			fflush(stdout);
			scanf("%d%d",&x,&y);
		}
		if(a[x][y]==‘F‘){
			return 0;
		}
		puts("R");
		fflush(stdout);
		scanf("%d%d",&x,&y);
		if(a[x][y]==‘F‘){
			return 0;
		}
		if(y==1){
			lr=1;
		}
	}
	else if((a[1][2]==‘.‘ || a[1][2]==‘F‘) && (a[2][1]==‘.‘ || a[2][1]==‘F‘)){
		puts("R");
		fflush(stdout);
		scanf("%d%d",&x,&y);
		if(x==1 && y==1){
			lr=1;
			puts("D");
			fflush(stdout);
			scanf("%d%d",&x,&y);
			if(num[x][y]==End){
				return 0;
			}
			if(x==1 && y==1){
				ud=1;
			}
		}
		else{
			if(num[x][y]==End){
				return 0;
			}
			puts("L");
			fflush(stdout);
			scanf("%d%d",&x,&y);
			puts("D");
			fflush(stdout);
			scanf("%d%d",&x,&y);
			if(num[x][y]==End){
				return 0;
			}
			if(x==1 && y==1){
				ud=1;
			}
		}
	}

	spfa(num[x][y]);
	int U=End;
	while(U!=num[x][y]){
		path[++p]=ma[U];
		U=pre[U];
	}
	path[++p]=ma[num[x][y]];
	for(int i=p;i>1;--i){
		if(path[i-1].first-path[i].first==1){
			puts(ud ? "U" : "D");
			fflush(stdout);
			scanf("%d%d",&x,&y);
		}
		if(path[i-1].first-path[i].first==-1){
			puts(ud ? "D" : "U");
			fflush(stdout);
			scanf("%d%d",&x,&y);
		}
		if(path[i-1].second-path[i].second==1){
			puts(lr ? "L" : "R");
			fflush(stdout);
			scanf("%d%d",&x,&y);
		}
		if(path[i-1].second-path[i].second==-1){
			puts(lr ? "R" : "L");
			fflush(stdout);
			scanf("%d%d",&x,&y);
		}
	}
	return 0;
}
时间: 2024-10-13 15:20:34

【分类讨论】【spfa】【BFS】Codeforces Round #416 (Div. 2) D. Vladik and Favorite Game的相关文章

Codeforces Round #416 (Div. 2) C. Vladik and Memorable Trip

题目链接:Codeforces Round #416 (Div. 2) C. Vladik and Memorable Trip 题意: 给你n个数,现在让你选一些区间出来,对于每个区间中的每一种数,全部都要出现在这个区间. 每个区间的价值为该区间不同的数的异或值,现在问你这n个数最大的价值是多少. 题解: 比赛的时间直接就想到了做法,不过在选取合法区间的时候,细节上出了点小问题. 然后一直wa到怀疑人生.太菜了. 首先,先将合法的区间选取出来. 对于这些区间,按照左端点排序, 然后对于选出来的

Codeforces Round #416 (Div. 2) 811D Vladik and Favorite Game

题目链接: http://codeforces.com/problemset/problem/811/D 题目描述: D. Vladik and Favorite Game This is an interactive problem. Vladik has favorite game, in which he plays all his free time. Game field could be represented as n?×?m matrix which consists of ce

(线段树+并查集) Codeforces Round #416 (Div. 2) E Vladik and Entertaining Flags

In his spare time Vladik estimates beauty of the flags. Every flag could be represented as the matrix n?×?m which consists of positive integers. Let's define the beauty of the flag as number of components in its matrix. We call component a set of cel

【动态规划】 Codeforces Round #416 (Div. 2) C. Vladik and Memorable Trip

划分那个序列,没必要完全覆盖原序列.对于划分出来的每个序列,对于某个值v,要么全都在该序列,要么全都不在该序列. 一个序列的价值是所有不同的值的异或和.整个的价值是所有划分出来的序列的价值之和. 求整个的价值的最大值 f(i)表示最后一个划分序列的右端点为i时,1~i的答案. f(i)=max{max{f(j)}(1<=j<i)+xorsum(j+1,i)(j+1到i的区间合法)}(1<=i<=n) 需要在转移的时候,顺便处理f(i)的前缀max. 最终的答案就是所有f(i)的最大

DFS/BFS Codeforces Round #301 (Div. 2) C. Ice Cave

题目传送门 1 /* 2 题意:告诉起点终点,踩一次, '.'变成'X',再踩一次,冰块破碎,问是否能使终点冰破碎 3 DFS:如题解所说,分三种情况:1. 如果两点重合,只要往外走一步再走回来就行了:2. 若两点相邻, 4 那么要不就是踩一脚就破了或者踩一脚走开再走回来踩一脚破了:3. 普通的搜索看是否能到达, 5 若能还是要讨论终点踩几脚的问题:) 6 DFS 耗时大,险些超时,可以用BFS来做 7 */ 8 #include <cstdio> 9 #include <algorit

BFS Codeforces Round #297 (Div. 2) D. Arthur and Walls

题目传送门 1 /* 2 题意:问最少替换'*'为'.',使得'.'连通的都是矩形 3 BFS:搜索想法很奇妙,先把'.'的入队,然后对于每个'.'八个方向寻找 4 在2*2的方格里,若只有一个是'*',那么它一定要被替换掉 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorithm> 9 #include <cstring> 10 #include <queue> 1

Codeforces Round #416 (Div. 2) A+B

A. Vladik and Courtesy 2 seconds 256 megabytes At regular competition Vladik and Valera won a and b candies respectively. Vladik offered 1 his candy to Valera. After that Valera gave Vladik 2 his candies, so that no one thought that he was less gener

Codeforces Round #416 (Div. 2)

B 前几天听cwy说O(m*n)被卡常,比赛时犹豫了好久才写,然后就A了,STL的常数很牛逼 大概2种方法:根据下标位置判断这个数值是否改变(找k-th min): 根据值来确定其下标,判断下标是否改变(找这个数是第几小,常数小) C n^2 dp,当时加了一些mark,实际上由于0?≤?ai?≤?5000,完全可以每次dp memset一波 D 交互题. 比赛时因为有一个for把3写成4,导致内存溢出,调了1个多小时都没有发现,还是太粗心(不过即使如此好像rank还是挺前面的..) 真可惜呀,

(dp) Codeforces Round #416 (Div. 2)

Vladik often travels by trains. He remembered some of his trips especially well and I would like to tell you about one of these trips: Vladik is at initial train station, and now n people (including Vladik) want to get on the train. They are already