github:https://github.com/micheallll/G
解题思路
主要的解题想法来源于网上的一个思路:将一个数独按一定规则变换后形成一个新的数独。思考后想到了几种换法,这次作业中主要采取了以下两种换法。
1.将所有行或所有列中的两个数交换位置,如:将所有行中的2和3交换位置。
2.将九行按每三行分成一组,共三组。一组中的任意两行可以互换,列也是相同规则。如:将第4行和第5行互换,将第8列和第9列互换。
设计实现
先输入一个内置数独。因为数独的第一个数要求为1,所以第一种换法只能从2-9中随机选出两个数,第二种换法不能交换第一列或第一行。根据排列组合可以产生两亿多种不同的数独。因为每次变换后都会生成新数独,所以变换一次就可以输出一次。
代码说明
因为自己代码水平不足,所以使用了比较简单的代码来实现算法。数独用二维数组来表示,换法用简单的循环嵌套完成。
第一种换法:先确定两个随机数,两个随机数要保证不相等。通过循环嵌套来确定行中随机数的位置,再进行交换。
代码:
x=(rand()%8)+2;//生成第一个随机数
y=x;
while(y==x) y=(rand()%8)+2;//生成第二个随机数,且与第一个随机数不相等
for(i=0;i<9;i++){
for(j=0;j<9;j++) if(sudo[i][j]==x){
tmp=sudo[i][j];
for(k=0;k<9;k++) if(sudo[i][k]==y){
sudo[i][j]=sudo[i][k];
sudo[i][k]=tmp;
break;//两个数交换完成后结束此次查找
}
break;
}
}
第二种换法:用循环来交换二维数组中的两行或两列。
代码:
for(j=0;j<9;j++)//交换两行
{
tmp=sudo[i][j];
sudo[i][j]=sudo[i+1][j];
sudo[i+1][j]=tmp;
}
for(j=0;j<9;j++)//交换两列
{
tmp=sudo[j][i];
sudo[j][i]=sudo[j][i+1];
sudo[j][i+1]=tmp;
}
输出代码也是简单的循环嵌套,这里就不放出来了。
测试运行
运行测试
N=10000耗时
N=1000000耗时
遇到的困难及解决方法
- 存在输出重复的可能。数独是通过变换随机产生的,虽然可以生产两亿种不同的数独(两亿分之百万重复的概率不到0.5%),但还是存在重复的可能性。想不出查重复的算法的情况下,我想到的解决方法是通过增加变换的方式来增加数独的个数,从而再降低输出重复的几率。比如三行三列同时交换,或者将整个数独盘进行反转或者旋转。
- 运行时间较长。因为算法不同,还有代码简单的原因,运行的时间相较于其他同学用时更多。对此还没想出什么好的解决方法。。
PSP
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 900 | 1200 |
· Estimate | · 估计这个任务需要多少时间 | 900 | 1200 |
Development | 开发 | 810 | 1050 |
· Analysis | · 需求分析 (包括学习新技术) | 120 | 120 |
· Design Spec | · 生成设计文档 | 0 | 0 |
· Design Review | · 设计复审 (和同事审核设计文档) | 0 | 0 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 30 | 30 |
· Design | · 具体设计 | 60 | 180 |
· Coding | · 具体编码 | 480 | 600 |
· Code Review | · 代码复审 | 45 | 30 |
· Test | · 测试(自我测试,修改代码,提交修改) | 75 | 90 |
Reporting | 报告 | 90 | 150 |
· Test Report | · 测试报告 | 0 | 0 |
· Size Measurement | · 计算工作量 | 50 | 70 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 40 | 80 |
合计 | 900 | 1200 |
个人体会及总结
要是放在以前,我可能问问同学的思路,模仿一下他们的代码就过去了。可能是自己对数独也有点兴趣,所以想自己试试,想出来的方法也是比较取巧。但是因为自己水平不足,加上时间安排上的仓促,所以写出来的代码质量不是很高。但是这次作业我还是学到了不少的东西,特别是vs,git上面。之前没用过是真的不会操作,还好有助教和同学的帮助。不过代码水平还是太薄弱了,希望能通过每次作业都有所提高。