您的位置:首页 > 其它

POJ1321棋盘问题(AC2)

2015-11-10 09:34 281 查看
棋盘问题

Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 29595 Accepted: 14667
Description
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
Input
输入含有多组测试数据。

每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 ,  k <= n

当为-1 -1时表示输入结束。

随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。

Output
对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。
Sample Input
2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1

Sample Output
2
1

 

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

//做到一半就卡住了,原因在于如果两个for循环,先扫行再扫列,扫完第一行,再扫第二行,那这样就会有重复的耶,后来想了个办法,输入有行号,按行号来

/*第一次提交lte超时 之前加了个for (i = hang; i < n; i++) 这个循环是不需要的,*/

#define MAXINT 10

int n = 0;
int k = 0;

int  ans = 0;
char map[MAXINT][MAXINT];
int visithang[MAXINT];
int visitlie[MAXINT];

void init()
{
int i = 0;
int j = 0;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
map[i][j]   = '\0';
}
visithang[i] = 0;
visitlie[i] = 0;
}

ans = 0;
return;
}

void dfs(int hang,int num)
{
//int i = 0;
int j = 0;
if (num == k)
{
ans += 1;
return;
}
if (hang >n) return;
if ((n-hang) < (k-num)) return;//剩下的行数还不够棋子的个数,直接return
//for (i = hang; i < n; i++)
//{
for (j = 0; j < n;j++)
{
//if (1 == visithang[hang]) break;
if (1 == visitlie[j])  continue;
if ('.' == map[hang][j]) continue;
//visithang[i] = 1;
visitlie[j] = 1;
dfs(hang+1,num + 1);
//回溯
//visithang[i] = 0;
visitlie[j]  = 0;
}
//}
/*4 2
#...
##..
...#
..#.
像这样的数据第一行第二行便利完,还得遍历第一行,第三行啊	*/
dfs(hang+1,num );  //这个很关键,自己写的时候还是会有点参考,就是这样的,num不+1表示hang这行没放,比如第0行然后第1行,第一行不放就是第2行
return;
}

int main()
{
int i = 0;
int j = 0;
int num = 0;
freopen("input.txt","r",stdin);
while (2 == scanf("%d %d", &n, &k) && (-1 != n) && (-1 != k))
{
init();
for (i = 0; i < n;i++)
{
scanf("%s", &map[i]);
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if ('#' == map[i][j]) ans++;
}
}

if (1 != k)
{
ans = 0;
dfs(0,0); //从0行开始,后面那个是放置的棋子个数
}
printf("%d\n",ans);
}
return 0;
}

 

 

//第二次就这样糊里糊涂的通过了

#include <stdio.h>
//POJ1321棋盘问题
#define MAXINT 10
char map[MAXINT][MAXINT];
int ans = 0;
int n = 0;
int w = 0;
int visithang[MAXINT]; //表示哪行已经被占领了
int visitlie[MAXINT];//表示哪列已经被占领了
//棋盘问题不是一个很好解决的问题吗?怎么自己也卡盒了。。。。自己学了那么久就到底是在干嘛,今天开始要复习复习复习。。。
//这样就一次AC了,不相信啊不相信
void init()
{
int i = 0;
int j = 0;
for (i = 0; i < MAXINT; i++)
{
for (j = 0; j < MAXINT; j++)
{
map[i][j] = '\0';
}
visithang[i] = 0;
visitlie[i]  = 0;
}
ans = 0;
return;
}

void dfs(int x, int y, int num) //num表示放了几个棋子了
{
int i = 0;
int j = 0;
if ((x<0)||(x>=w)||(y<0)||(y>=w)) return;
if (num == n)
{
ans += 1;
return;
}

for (i = x; i < w; i++)
{
for (j = 0; j < w; j++)
{
if (visithang[i]) continue;
if (visitlie[j]) continue;
if ('.' == map[i][j]) continue;
visithang[i] = 1;
visitlie[j] = 1;
dfs(i,j,num+1);
visithang[i] = 0;
visitlie[j] = 0;
}
}

//但是这样写不对耶。。。会有错误答案
//dfs(x+1, 0, 0); //防止有多行的出现,即行号比棋子多的情况
return;
}

//n <= 8 , k <= n因为最大只有8所以可以用DFS
int main()
{
int i = 0;
int j = 0;
freopen("input.txt","r",stdin);
while ((2 == scanf("%d %d",&w,&n))&&(-1 != w)&&(-1 != n))
{
init();
for (i = 0; i < w;i++)
{
scanf("%s", &map[i]);
}
dfs(0, 0, 0);
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: