您的位置:首页 > 其它

USACO 1.5 Checker Challenge (DFS + 剪枝)

2015-09-27 00:24 459 查看
#include <stdio.h>
#define DEBUG 1
#define TESTCASES 8
#define IN(x)  ( (x) >= 1 && (x) <= size ? 1 : 0 )
#define WITHIN(x, y) ( IN(x) && IN(y) ? 1 : 0 )
int size;
int sizeIsEven;
int halfSize;
int conflict[14][14];
int solution[14];
int numOfSolutions;
//剪枝:对角线冲突只要标记左下和右下两个方向
int directionArray[2][2] = {{1, 1}, {1, -1}};

void printConflict(){
int i, j;
for (i = 1; i <= size; i++)
for (j = 1; j <= size; j++)
printf("%d%c", conflict[i][j], j == size ? '\n' : ' ');
printf("\n");
}

void setConflict(int row, int column, int flag){
int i;
for (i = 1; i <= size; i++)
conflict[i][column] += flag;
int directionIndex;
for (directionIndex = 0; directionIndex < 2; directionIndex++){
int deltaX = directionArray[directionIndex][0];
int deltaY = directionArray[directionIndex][1];
int x = row + deltaX;
int y = column + deltaY;
while ( WITHIN(x, y) ){
conflict[x][y] += flag;
x += deltaX;
y += deltaY;
}
}
}

void placeQueen(int row, int sum){
//printConflict();
if (row == size){
//剪枝:最后一行放棋子的列号可以算出来
int temp = (1 + size) * size / 2 - sum;
if (conflict[size][temp] == 0){
solution[size] = temp;
if (++numOfSolutions < 4){
int i;
for (i = 1; i <= size; i++)
printf("%d ", solution[i]);
printf("\n");
}
}
return;
}
int column;
for (column = 1; column <= size; column++){
//剪枝:size为偶数时对称优化,size为奇数时怎么优化呢?
if ( row == 1 && sizeIsEven && column  ==  halfSize + 1 && numOfSolutions >= 3){
numOfSolutions *= 2;
return;
}
if (conflict[row][column] == 0){
solution[row] = column;
setConflict(row, column, 1);
placeQueen(row + 1, sum + column);
setConflict(row, column, -1);

}
}
}

int main(){
#if DEBUG
int testCase;
for (testCase = 1; testCase <= TESTCASES; testCase++){
char inputFileName[20] = "inputx.txt";
inputFileName[5] = '1' +  (testCase - 1);
freopen(inputFileName, "r", stdin);
printf("\n#%d\n", testCase);
#endif

scanf("%d", &size);
halfSize = size >> 1;
sizeIsEven = !(size & 1);

numOfSolutions = 0;
placeQueen(1, 0);
printf("%d\n", numOfSolutions);

#if DEBUG
}
#endif
return 0;
}









                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息