uva 639 Don't Get Rooked ( 回溯 )

这道题确实是标准的回溯,果然还是早上比较清醒一些,昨天晚上想了好长一会儿都没有想起来,早上一会的功夫就A

了,估计也有昨天晚上的帮助。。。总感觉不想写太多私人的东西在这上面,因为这个是每个人都可以无条件访问的。。。

思路:

由于数据比较小,可以把每个元素都遍历一遍,回溯选择,最多4*4,还是很小的,我交的才1ms,1A。。

贴代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int map[10][10];
int visit[10][10];
int row[10];//用来判断该行是否可以放置 
int col[10];//用来判断该列是否可以放置 
int max,cnt,n;
void solve(int x,int y)//x,y表示将要访问的行数和列数 
{
	for(int i=x; i<=n; i++)
	{
		for(int j=y; j<=n; j++)
		{
			if(map[i][j] == 'X')//如果有墙了,就说明这一行和这一列以后可以放置了 
			{
				row[i] = 0;
				col[j] = 0;
				
			}
			else if(visit[i][j] == 0 && col[j] == 0  && row[i] == 0)//没有访问过+该行可以访问+该列可以访问 
			{
				cnt++;
				if(cnt > max)
					max = cnt;
				visit[i][j] = 1;
				row[i] = 1;
				col[j] = 1;
				if(x<n && y<n)
					solve(x, y+1);
				else if(x<n && y==n)
					solve(x+1, 1);
				else if(x == n && y < n)
					solve(x,y+1);
				else if(x == n && y == n)
					return ;
				visit[i][j] = 0;// 回溯 
				row[i] = 0;//回溯 
				col[j] = 0;//回溯 
				cnt--;//回溯 
			}
		}
	}
	return ;
}
int main()
{
	int i,j;
	while(scanf("%d",&n),n!=0)
	{
		memset(visit,0,sizeof(visit));
		memset(row,0,sizeof(row));
		memset(col,0,sizeof(col));
		memset(map,'\0',sizeof(map));
		getchar();
		for(i=1; i<=n; i++)
		{
			for(j=1; j<=n; j++)
			{
				scanf("%c",&map[i][j]);
			}
			getchar();
		}
		max = 0;
		cnt = 0;
		solve(1,1);
		printf("%d\n",max);
	}
	return 0;
} 

你可能感兴趣的:(uva 639 Don't Get Rooked ( 回溯 ))