16宫格问题,和8皇后差不多。想了整整1个大白天了,不知道问题出在哪。

renzha0013 2011-04-23 08:44:51
4行4列宫格,每行列,只能放2个子,
下面是我的代码,可是我的代码只能输出一个结果,而且再怎么改都还是同样的结果。求高手帮忙一下,我卡在这边了。
#include<iostream>
using namespace std;

void printf4(int a[][4]) //输出
{
int br=0;
for(int i1=0;i1<4;i1++)
for(int j1=0;j1<4;j1++)
{ cout<<a[i1][j1]<<" ";
br++;
if(br%4==0)
cout<<endl;
}

}


void putin(int a[][4],int m,int n,int*row,int*how) //输入点
{

a[m][n]=1;
row[m]++;
how[n]++;


}


bool couldputin(int a[][4],int m,int n,int *row,int *how) //判断是否可以输入。
{
if((m<4)&&(n<4)&&(row[m]!=2)&&(how[n]!=2)&&(a[m][n]!=1))
return true;
else
return false;
}


void set8(int a[][4],int * row,int* how,int ip) //输入8个点,每行2个,每列2个,
{
if(ip>4)
{ printf4(a);cout<<endl;}
else
{
for(int i=0;i<3;i++)
{
if (couldputin(a,ip,i,row,how))
{ putin(a,ip,i,row,how);
for(int j=i+1;j<4;j++)
{
if (couldputin(a,ip,j,row,how))
{
putin(a,ip,j,row,how);
set8(a,row,how,ip+1);
}
}
}


}
}


}









int main()
{

int a[4][4];
int i,j;


for(i=0;i<4;i++)
for(j=0;j<4;j++)
a[i][j]=0;

int row[4]={0,0,0,0}; //行, 每行输入的个数,最多为2.
int how[4]={0,0,0,0}; //列 每列输入的个数,最多为2.


int ip=0;






set8(a,row,how,0);


printf4(a);


return 0;
}
...全文
187 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
renzha0013 2011-05-16
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 yu997948259 的回复:]

受益匪浅…………
[/Quote]

我也是这道题做后感觉学到很多。
yu997948259 2011-05-16
  • 打赏
  • 举报
回复
受益匪浅…………
riyueming184 2011-04-25
  • 打赏
  • 举报
回复
我不知道我对你问题的理解是否是对的,下面是我的代码:
void printf4(int a[][4]) //输出
{
int br=0;
for(int i1=0;i1<4;i1++)
for(int j1=0;j1<4;j1++)
{ cout<<a[i1][j1]<<" ";
br++;
if(br%4==0)
cout<<endl;
}
}


void putin(int a[][4],int m,int n,int*row,int*how) //输入点
{

a[m][n]=1;
row[m]++;
how[n]++;


}


bool couldputin(int a[][4],int m,int n,int *row,int *how) //判断是否可以输入。
{
if((m<4)&&(n<4)&&(row[m]!=2)&&(how[n]!=2)&&(a[m][n]!=1))
return true;
else
return false;
}

void set8(int a[][4],int * row,int* how,int ip) //输入8个点,每行2个,每列2个,
{
srand((unsigned)time(0));
if(ip>4)
{ printf4(a);cout<<endl;}
else
{
int i = 1;
while(i <= 8)
{
int p,q;
p = rand()%4;
q = rand()%4;
if (couldputin(a,p,q,row,how))
{
putin(a,p,q,row,how);
i++;
}
}
}
}

int main()
{

int a[4][4];
int i,j;


for(i=0;i<4;i++)
for(j=0;j<4;j++)
a[i][j]=0;

int row[4]={0,0,0,0}; //行, 每行输入的个数,最多为2.
int how[4]={0,0,0,0}; //列 每列输入的个数,最多为2.


int ip=0;

set8(a,row,how,0);


printf4(a);

return 0;
}
只是修改了set8函数,原因是你错误的使用了for循环,逻辑上当然只有一条道,应该使用随机函数寻找输入点。
renzha0013 2011-04-25
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 riyueming184 的回复:]

我想我理解你的要求了,以下是修改后代码,主要修改set8函数,main函数只是将0用ip替换:
void printf4(int a[][4]) //输出
{
int br=0;
for(int i1=0;i1<4;i1++)
for(int j1=0;j1<4;j1++)
{ cout<<a[i1][j1]<<" ";
br++;
if(br%4==0)
cout<<endl……
[/Quote]真是感谢你,我懂了。这个问题困惑了我3天了。
riyueming184 2011-04-25
  • 打赏
  • 举报
回复
我想我理解你的要求了,以下是修改后代码,主要修改set8函数,main函数只是将0用ip替换:
void printf4(int a[][4]) //输出
{
int br=0;
for(int i1=0;i1<4;i1++)
for(int j1=0;j1<4;j1++)
{ cout<<a[i1][j1]<<" ";
br++;
if(br%4==0)
cout<<endl;
}
}


void putin(int a[][4],int m,int n,int*row,int*how) //输入点
{

a[m][n]=1;
row[m]++;
how[n]++;


}


bool couldputin(int a[][4],int m,int n,int *row,int *how) //判断是否可以输入。
{
if((m<4)&&(n<4)&&(row[m]!=2)&&(how[n]!=2)&&(a[m][n]!=1))
return true;
else
return false;
}
//ip修改为传址,以便修改行标记
void set8(int a[][4],int * row,int* how,int& ip) //输入8个点,每行2个,每列2个,
{
// srand((unsigned)time(0));
if(ip>=4)
{
ip--;//ip==4时,说明第四行已经完成,现在ip处于第五行,需要减一回到上一行
printf4(a);
cout<<endl;
}
else
{
for(int i=0;i<3;i++)
{
if (couldputin(a,ip,i,row,how))
{
putin(a,ip,i,row,how);
for(int j=i+1;j<4;j++)
{
if (couldputin(a,ip,j,row,how))
{
putin(a,ip,j,row,how);
ip++;
set8(a,row,how,ip);
}
//第二个点输入完成之后,如果进入到这里,则说明已经完成一个4x4宫格,需要将此点重置,并将每行每列相应数值减一
if (a[ip][j]==1)
{
a[ip][j]=0;
row[ip]--;
how[j]--;
}
}

}
//此点以下遍历完成,理由同上
if (a[ip][i]==1)
{
a[ip][i]=0;
row[ip]--;
how[i]--;
}
}
//退出一行之前,将相应变量清空
for (int k = 0;k < 4; ++k)
{
if (a[ip][k] == 1)
{
a[ip][k] = 0;
row[ip]--;
how[k]--;
}
}
ip--;//进入上一行,重新遍历
}
}

int main()
{

int a[4][4];
int i,j;


for(i=0;i<4;i++)
for(j=0;j<4;j++)
a[i][j]=0;

int row[4]={0,0,0,0}; //行, 每行输入的个数,最多为2.
int how[4]={0,0,0,0}; //列 每列输入的个数,最多为2.


int ip=0;

set8(a,row,how,ip);
return 0;
}

你的疏忽主要在于没有进行回溯,导致只有一个输出。
renzha0013 2011-04-25
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 riyueming184 的回复:]

我说我不太理解你的一个输出指的是什么?按我的修改后的程序,在vs2010上,运行结果可能是:
0101
1010
0110
1001
重新运行又有输出:
0011
0110
1001
1100
如果我的理解不对,你说清楚一点。
[/Quote]我要输出的是所有 每行每列只有2个 的所有情况。
riyueming184 2011-04-25
  • 打赏
  • 举报
回复
我说我不太理解你的一个输出指的是什么?按我的修改后的程序,在vs2010上,运行结果可能是:
0101
1010
0110
1001
重新运行又有输出:
0011
0110
1001
1100
如果我的理解不对,你说清楚一点。
renzha0013 2011-04-25
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 riyueming184 的回复:]

我不知道我对你问题的理解是否是对的,下面是我的代码:
void printf4(int a[][4]) //输出
{
int br=0;
for(int i1=0;i1<4;i1++)
for(int j1=0;j1<4;j1++)
{ cout<<a[i1][j1]<<" ";
br++;
if(br%4==0)
cout<<endl;
}
}

……
[/Quote]可是你的代码也自由一个输出。
renzha0013 2011-04-24
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 yu997948259 的回复:]

我比较了一下和八皇后问题,程序就是没有多次循环,循环了一次找到了一个结果就返回了,可是和八皇后还不一样,八皇后是一个点,而这个程序是每行两个点,我也郁闷着呢,呵呵
[/Quote]我想了2天了,卡在这边。
yu997948259 2011-04-24
  • 打赏
  • 举报
回复
我比较了一下和八皇后问题,程序就是没有多次循环,循环了一次找到了一个结果就返回了,可是和八皇后还不一样,八皇后是一个点,而这个程序是每行两个点,我也郁闷着呢,呵呵
renzha0013 2011-04-24
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 yu997948259 的回复:]

想了好半天,可是还是不会……
[/Quote]还是要谢谢你,呵呵
renzha0013 2011-04-24
  • 打赏
  • 举报
回复
有没有高手来帮忙啊。
yu997948259 2011-04-24
  • 打赏
  • 举报
回复
想了好半天,可是还是不会……
renzha0013 2011-04-24
  • 打赏
  • 举报
回复
哎,调试了2天了,郁闷。
renzha0013 2011-04-24
  • 打赏
  • 举报
回复
求高手帮忙。
renzha0013 2011-04-23
  • 打赏
  • 举报
回复
郁闷啊。
renzha0013 2011-04-23
  • 打赏
  • 举报
回复
十分着急啊。求救啊!!

64,651

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧