求网格中的黑点分布。现有6*7的网格,在某些格子中有黑点,已知各行与各列中有黑点的点数之和,请在这张网格中画出黑点的位置。
#include<stdio.h>
#define ROWS 6
#define COLS 7
int iPointsR[ROWS] = {2,0,4,3,0};
//各行黑点数和的情况
int iPointsC[COLS] = {4,1,2,2,1,2,1};
//各列黑点数和的情况
int iCount,iFound;
int 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,有解
}
}
else
{
for(int iColNo = 0; iColNo < COLS;iColNo++)
{
if(iPointsR[iRowNo] == 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!");//该种情况下的网格不存在
}
// FindBlackPoint.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "stdlib.h"
//求网格中的黑点分布。现有6*7的网格,在某些格子中有黑点,
//已知各行与各列中有黑点的点数之和,请在这张网格中画出黑点的位置。
#include<stdio.h>
#define ROWS 6
#define COLS 7
int iPointsR[ROWS] = {2,3,2,3,2,4};
//各行黑点数和的情况
int iPointsC[COLS] = {3,2,2,2,2,3,2};
//各列黑点数和的情况
int iCount,iFound;
int iSumR[ROWS],iSumC[COLS],Grid[ROWS][COLS];
void printArray()
{
for(int i = 0;i < ROWS; i++)
for(int j = 0;j < COLS;j++)
printf("%d%c",Grid[i][j],(j == COLS-1) ? '\n' : ' ');
}
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);
printArray();
iFound = 1;//iFound = 1,有解
system("pause");
}
}
else
{
for(int iColNo = 0; iColNo < COLS;iColNo++)
{
if(iPointsR[iRowNo] == 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;//用于判断是否有解
}
void main(int argc,char* argv[])
{
if(!Set(0))
printf("Failure!");//该种情况下的网格不存在
}
// BlackPoint.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "stdlib.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];
void printResult()
{
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');
}
void Set(int iRowNo)//逐行试探求解,行只管堆出满足行条件的,列再按列条件筛选!
{
if(iRowNo==ROWS)
{
//Check columns , and printResult if OK
for(int iColNo=0; iColNo < COLS ; iColNo++)
{
if(iSumC[iColNo] != iPointsC[iColNo])
break;
}
if(iColNo == COLS )// 满足条件,输出解
{
printResult();
system("pause");
iFound = 1; // iFound = 1,表明有解
}
}
else
{
//Try,Check Rows ,Re-In-Try
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 ; // 用于判断是否有解
}
int main(int argc, char* argv[])
{
iFound=0;
Set(0);
if(iFound==0)
printf("Failure!");
return getchar();
}