uva 639

来源:互联网 发布:网络兼职赚钱是真的吗 编辑:程序博客网 时间:2024/06/17 08:43

一道类似于8皇后的回溯题。一开始老想不通怎么回溯,准备直接暴力的,估计都会TLE。也没写。

参考了下别人代码,八皇后为逐行填写,此问题因为有墙,所以同一行可以放置,应该从左到右依次放子

题目:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=580

AC代码:

#include<stdio.h>#define MAX 8char map[MAX][MAX],n;int vis[MAX][MAX];            //数组开大一点,最外层相当于围了一层墙,不可以放棋子int ok_place(int i,int j){int left,up;for(left=j-1;left>=0;left--){if(vis[i][left]==-1)     break;         //左边有墙,可以放if(vis[i][left]==0)  //有子return 0;}for(up=i-1;up>=0;up--){if(vis[up][j]==-1)break;           //上面有墙if(vis[up][j]==0)return 0;        //上面有子}return 1;}int dfs(int i,int j,int m){               //i行,j列int count=0,max=0;while(i<m){if(vis[i][j]&&(vis[i][j]!=-1)&&ok_place(i,j)){vis[i][j]=0;          //表示已经放子了count=dfs(i,j+1,m)+1;if(max<count)max=count;vis[i][j]=1;          //恢复到未回溯前的状态}if(j>=m-1){                //采用从左到又的方式放子,所以判断是否可以放的时候也只要向左和向上判断i++;                   //放到了最左边应该换一行了j=0;}elsej++;}return max;}int main(){int i,j,maxsum;while(scanf("%d",&n)!=EOF&&n){for(i=0;i<n;i++){scanf("%s",map[i]);for(j=0;j<n;j++){if(map[i][j]=='X')vis[i][j]=-1;         //-1代表有墙elsevis[i][j]=1;          //1是代表可以放子}}maxsum=0;maxsum=dfs(0,0,n);printf("%d\n",maxsum);}return 0;}