题目出自山东理工ACM: http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Index/problemdetail/pid/1025.html
题目描述:在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。输入含有多组测试数据。 每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n 当为-1 -1时表示输入结束。 随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
输入example:
2 1 #. .# 4 4 ...# ..#. .#.. #... -1 -1输出example:
2 1---------------------------------------------------- ---------------------------------------------------- -----------------------------------------------
用深度优先搜索的方法:
大体思路可以想象为, 从图的(0,0)点出发到(n, n)点的搜索过程:从上往下,从左往右,查看该点是否是满足要求的点,如果是满足要求的,将 满足要求的棋子个数 numOfChessSatisfied 加 1,(对于这个数,在不同的递归栈里有不同的结果), 等到numOfChessSatisfied == chess_piece(达到龟腚的棋子数目的时候),结果加上一种可能就行了。until将该棋盘上所有的遍历完。
这个算法效率不高,最起码有一定的时间浪费,
For Example:
4 3 ...# row 1 ..#. row 2 .##. row 3 #..# row 4
这个时候, 最外层的递归查找 (栈底的查找) 在 row3 以后就没有意义了浪费时间。。。想想怎么改...
-------------------------------------------------------------------------------------------------------------------------------------------------------
#include<iostream>
#include<vector>
using namespace std;
int countOfWay = 0;
int row, chess_piece;
char chessBoard[9][9]; // matrix model
bool isAvaliable(int row_, int col_)
{
for(int i = 1; i <= row ; i++ ){
if(chessBoard[row_][i] == '!') //A Chess has been placed on a row, that row can not place any other chess piece .
return false;
}
for(int i = 1; i <= row ; i++ ){ // tow chess cannot in the same colum.
if(chessBoard[i][col_] == '!')
return false;
}
return true;
}
void chess_DepthFirstSearch(int step, int numOfChieceStatisfied){
if(numOfChieceStatisfied == chess_piece){
countOfWay++;
return;
}
if(step > row * row )
return;
int row_ = step / row + 1;
int col_ = step % row + 1;
if( chessBoard[row_][col_] == '#' && isAvaliable(row_, col_) ){
chessBoard[row_][col_] = '!';
chess_DepthFirstSearch(step + 1, numOfChieceStatisfied + 1);
chessBoard[row_][col_] = '#';
}
chess_DepthFirstSearch(step + 1, numOfChieceStatisfied);
}
int main(){
while(cin >> row >> chess_piece){
if(row == -1 && chess_piece == -1)
return 0;
for(int row_ = 1; row_ < row + 1; row_++){
for(int col_ = 1; col_ < row + 1 ; col_++){
std::cin >> chessBoard[row_][col_];
}
}
chess_DepthFirstSearch(0, 0);
cout<< countOfWay <<endl;
countOfWay = 0;
/* output test for input
for(int row_ = 1; row_ < row + 1; row_++){
for(int col_ = 1; col_ < row + 1 ; col_++){
std::cout<<chessBoard[row_][col_];
}
std::cout<<'\n';
}
*/
}
return 0;
}
代码据 HQD因为有趣所以做题 而改动
后来交上去一直 Wrong Anwser... sigh..
然后写了个小小小小小python生产测试实列的脚本, 贴上了。
#gen-chessBoard.py
import random
import sys
testTimes = 20
while testTimes >= 0 :
row = random.randint(1,8)
cell_counts = row * row
count = cell_counts
HashDot_List = []
while count > 0 :
count -= 1
char = random.choice( ['#','.'] )
HashDot_List.append( char )
hash_num = HashDot_List.count('#')
print row , hash_num
count = 0
while count < cell_counts:
sys.stdout.write( HashDot_List[count] )
count += 1
if count%row == 0 :
print
print
testTimes -= 1
print -1, -1
接着重定位测试...
把写出的代码输出到文件a.out ax.out里
再用DOS的FC指令,比较两个文件内容,看看是不是一样
最后发现是由于没有归零。。。