#include "stdafx.h"
#define ROWS 6
#define COLS 7
int iPointsR[ROWS] = {2, 0, 4, 3, 4, 0}; // 各行点数和的情况
int iPointsC[COLS] = {4, 1, 2, 2, 1, 2, 1}; // 各列点数和的情况
int iCount, iFound, iSumR[ROWS], iSumC[COLS], Grid[ROWS][COLS];
int Set(int iRowNo)
{
// 到最后一行时,检查各列点数和是否满足条件,若满足条件,说明找到一个解
if(iRowNo == ROWS){
for(int iColNo=0; iColNo < COLS && iSumC[iColNo] == iPointsC[iColNo]; iColNo++)
if(iColNo == COLS - 1){ // 满足条件,输出解
printf("/nNo.%d:/n", ++iCount); // 打印解的序号
for(int i=0; i < ROWS; i++)
for(int j=0; j < COLS; j++)
printf("%d%c", Grid[i][j], (j+1) % COLS ? ' ' : '/n');
iFound = 1; // iFound = 1,表明有解
}
// 若还没有找到解,则对当前行所有列进行试探求解(若求一个解,则加判断!iFound去掉即可)
}else{
for(int iColNo=0; iColNo < COLS; iColNo++)
if(iPointsR[iRowNo] == 0) // 此行条件为点数和等于0,所以直接到下一行
Set(iRowNo + 1);
else if(Grid[iRowNo][iColNo]==0){ // 对还没放置的点进行试探求解
Grid[iRowNo][iColNo] = 1; // 在当前位置放置一个点
iSumR[iRowNo]++; iSumC[iColNo]++; // 将当前行、列点数和加一
// 当前行点数和不足,且当前列点数和未超过要求时,在当前行的其他位置继续放置黑点
if(iSumR[iRowNo] < iPointsR[iRowNo] && iSumC[iColNo] <= iPointsC[iColNo])
Set(iRowNo);
// 当前行点数和恰好等于要求,且当前行号没有超出下标范围时,在下一行继续放置黑点
else if(iSumR[iRowNo] == iPointsR[iRowNo] && iRowNo < ROWS)
Set(iRowNo + 1);
// 不满足上面两个或求出一个解时,进行回溯
Grid[iRowNo][iColNo] = 0;
iSumR[iRowNo]--; iSumC[iColNo]--;
}
}
return iFound; // 用于判断是否有解
}
int main(int argc, char* argv[])
{
if(!Set(0))
printf("Failure!");
return getchar();
}