题意:给定一个 n x n 的棋盘,在上面放置车。其中.号表示可放置,X表示墙。在同一行或同一列的两个车,如果它们之间没有X墙挡着,则是不合法的放置。给定一棋盘,最多可以放置车的数量。
思路:枚举所有的格子,看是否可以在此放置。每次放一个车后,修改棋盘的横行、竖列直到X的位置为1,即不可放置。因为要修改棋盘,所以需拷贝一个过来,修改拷贝的。还有一些注意的,如注释,总感觉写得不是很简洁。
还有就是,二维数组做参数时,可以用 char b[][5], 或者 char (*b)[5]。但不能是 char *b[5]。后面这个是声明一个5维的char指针数组额,需要像第二个那样用括号括起来表明b是一个指针,而不是数组。
Code:
#include<stdio.h> #include<string.h> void dfs(int cur,int n,char board[][5],int a,int b); int bestn; int main() { freopen("639.in","r",stdin); freopen("639.out","w",stdout); int n; char board[5][5]; while(scanf("%d",&n) && n) { for(int i=0;i<n;++i) scanf("%s",board[i]); bestn=0; dfs(1,n,board,0,0); printf("%d\n",bestn); } return 0; } void dfs(int cur,int n,char board[][5],int a,int b) {//尝试放置第cur个车,从[a,b]这个位置开始往后枚举尝试。 for(int i=a;i<n;++i) { int j=b;//从a行b列开始,但到下一行的时候是从0列而不是b列开始枚举。 if(i!=a) j=0; for(;j<n;++j) { if(board[i][j]=='.') { char bd2[5][5]; memcpy(bd2,board,sizeof(bd2)); for(int c=i;c<n;++c) if(bd2[c][j]!='X') bd2[c][j]='1'; else break; for(int c=j;c<n;++c) if(bd2[i][c]!='X') bd2[i][c]='1'; else break; dfs(cur+1,n,bd2,i+(j+1)/n,(j+1)%n); } } } cur--;//dfs是尝试放置第cur个车。枚举到n*n位置,这时的第cur个车肯定是放不了的。 bestn=cur>bestn?cur:bestn; }
//上一版本是按二维坐标枚举的,这里按一维坐标枚举,稍微简洁些。 #include<stdio.h> #include<string.h> void dfs(int cur,int n,char board[][5],int m); int bestn; int main() { freopen("639.in","r",stdin); freopen("639.out","w",stdout); int n; char board[5][5]; while(scanf("%d",&n) && n) { for(int i=0;i<n;++i) scanf("%s",board[i]); bestn=0; dfs(1,n,board,0); printf("%d\n",bestn); } return 0; } void dfs(int cur,int n,char board[][5],int m) { for(int i=m;i<n*n;++i) { int a=i/n; int b=i%n; if(board[a][b]=='.') { char bd2[5][5]; memcpy(bd2,board,sizeof(bd2)); for(int c=a;c<n;++c) if(bd2[c][b]!='X') bd2[c][b]='1'; else break; for(int c=b;c<n;++c) if(bd2[a][c]!='X') bd2[a][c]='1'; else break; dfs(cur+1,n,bd2,i+1); } } cur--; bestn=cur>bestn?cur:bestn; }
原文地址:http://blog.csdn.net/buxizhizhou530/article/details/44022045