题意:给定一个 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