CodeForces - 1316D Nash Matrix(构造+dfs)

题目链接:点击查看

题目大意:给出一个 n * n 的矩阵,初始时每个格子都为空,现在要求我们自己用 ' R ' , ' L ' , ' U ' , ' D ' 和 ' X ' 填充,分别表示在每个格子必须完成的指令,前四个分别为方向指令,代表着需要向指定的方向移动一个单位,而 ' X ' 代表终点,在这个点必须停下来,而在移动的过程中,不许越界,问能否找到一种构造方案,使得每个格子最终都能到达指定的格子,-1 -1 代表无限循环

题目分析:其实光考虑格子的属性,我们可以分为三种,一种是无限循环的,一种是终点,还有一种就是正常的路了,对于无限循环,第一反应应该是找到一个环,但后来反应过来了,我们只需要找到找到相邻的两个无限循环的格子,让其对起来这两个格子就形成一个最小的环了,与这两个格子直接相连的所有无限循环,都可以沿着路径到达这两个格子,这就是我处理无限循环的方法,剩下的就是关于 ‘ X ’ ,因为 ' X ' 可以视为终点,各个其他的点汇集而来的点,我们只需要从这个点出发,将沿路需要到达该点的所有点都连接过来就好了,经过上述两个操作后,矩阵中的所有点应该都有了一个确定的赋值,此时检查一遍,如果仍然有空缺,那就说明无解了,否则该矩阵就是答案了

比较简单的一道构造题,我感觉dfs写起来比bfs要简单不少,因为每个点至多遍历一遍,所以时间复杂度为O(n*n)

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
using namespace std;
      
typedef long long LL;
     
typedef unsigned long long ull;
      
const int inf=0x3f3f3f3f;
 
const int N=1e3+100;

const int b[4][2]={0,1,0,-1,1,0,-1,0};

const char pos[4]={'L','R','U','D'};

int n;

struct Node
{
	int x,y;
	char ch;
}point[N][N];

void dfs1(int x,int y)//处理无限循环
{
	for(int i=0;i<4;i++)
	{
		int xx=x+b[i][0];
		int yy=y+b[i][1];
		if(xx<=0||yy<=0||xx>n||yy>n)
			continue;
		if(point[xx][yy].ch!='T')
			continue;
		point[xx][yy].ch=pos[i];
		dfs1(xx,yy);
	}
}

void dfs2(int x,int y,int sx,int sy)//处理正常的路
{
	for(int i=0;i<4;i++)
	{
		int xx=x+b[i][0];
		int yy=y+b[i][1];
		if(xx<=0||yy<=0||xx>n||yy>n)
			continue;
		if(point[xx][yy].ch!='C')
			continue;
		if(point[xx][yy].x==sx&&point[xx][yy].y==sy)
		{
			point[xx][yy].ch=pos[i];
			dfs2(xx,yy,sx,sy);
		}
	}
}

bool check()
{
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if(point[i][j].ch=='T'||point[i][j].ch=='C')
				return false;
	return true;
}

int main()
{
#ifndef ONLINE_JUDGE
//	freopen("input.txt","r",stdin);
//	freopen("output.txt","w",stdout);
#endif
//	ios::sync_with_stdio(false);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
		{
			scanf("%d%d",&point[i][j].x,&point[i][j].y);
			if(point[i][j].x==i&&point[i][j].y==j)//终点
				point[i][j].ch='X';
			else if(point[i][j].x==-1&&point[i][j].y==-1)//无限循环
				point[i][j].ch='T';
			else//正常的路
				point[i][j].ch='C';
		}
	for(int x=1;x<=n;x++)//处理无限循环 
		for(int y=1;y<=n;y++)
			if(point[x][y].ch=='T')
				for(int k=0;k<4;k++)
				{
					int xx=x+b[k][0];
					int yy=y+b[k][1];
					if(xx<=0||yy<=0||xx>n||yy>n)
						continue;
					if(point[xx][yy].ch=='T')
					{
						point[x][y].ch=pos[k^1];
						point[xx][yy].ch=pos[k];
						dfs1(x,y);
						dfs1(xx,yy);
					}
				}
	for(int x=1;x<=n;x++)//处理制定路径
		for(int y=1;y<=n;y++)
			if(point[x][y].ch=='X')
				dfs2(x,y,x,y);
	if(!check())
		puts("INVALID");
	else
	{
		puts("VALID");
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
				putchar(point[i][j].ch);
			putchar('\n');
		}
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	return 0;
}
发布了672 篇原创文章 · 获赞 26 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_45458915/article/details/104679809