第31講 数独(ナンバープレイス)問題解決ソフトVer.2の制作
(数独(ナンバープレイス)問題作成ソフトに挑戦する人は☆☆)
第11話 第8話入力順の構築コード解説
コード再掲
void nyuryokujyunkoutiku(){
char i,j,k,gcn=0;
for(i=1;i<10;i++){
for(j=0;j<9;j++){
for(k=0;k<9;k++){
if(b[j][k]==i){
zy[gcn]=j;
zx[gcn]=k;
gcn++;
}
}
}
}
//以下は入力順の構築に成功しているかどうか確認のためのもの。成功が確認されたら削除する。
char k1=0,k2=0;
for(i=0;i<4;i++)for(j=0;j<13;j++)dataGridView1[j,4*i+28]->Value=L"*";
for(i=0;i<4;i++)for(j=0;j<13;j++)dataGridView1[4*i,j+28]->Value=L"*";
for(i=0;i<cn;i++){
if(a[zy[i]][zx[i]]==0){
if(zx[i]<3)xx=zx[i];
if(zx[i]>2 && zx[i]<6)xx=zx[i]+1;
if(zx[i]>5 && zx[i]<9)xx=zx[i]+2;
if(zy[i]<3)yy=zy[i];
if(zy[i]>2 && zy[i]<6)yy=zy[i]+1;
if(zy[i]>5 && zy[i]<9)yy=zy[i]+2;
dataGridView1[xx+1,yy+29]->Value=i;
}
}
for(i=0;i<81;i++){
if(a[i/9][i%9]>0){
if(i/9<3)yy=i/9;
if(i/9>2 && i/9<6)yy=i/9+1;
if(i/9>5 && i/9<9)yy=i/9+2;
if(i%9<3)xx=i%9;
if(i%9>2 && i%9<6)xx=i%9+1;
if(i%9>5 && i%9<9)xx=i%9+2;
dataGridView1[xx+1,yy+29]->Value=L"/";
}
}
}
コード解説
こちらは簡単な方の入力順の構築です。
最小値は
* | 6 | 5 | 3 | 5 | 4 | * | 5 | 5 |
3 | 5 | * | * | 5 | * | 5 | 4 | 5 |
5 | 7 | 6 | 5 | 6 | 5 | 8 | 6 | 6 |
5 | 7 | 6 | 3 | 6 | * | 5 | 6 | 5 |
4 | 7 | * | 1 | 4 | 4 | 5 | 6 | * |
4 | 5 | 4 | 3 | * | * | 5 | * | 4 |
3 | 4 | 4 | * | 4 | 3 | 5 | * | * |
* | 7 | 5 | 5 | 5 | 4 | 5 | 5 | 6 |
* | 6 | 4 | * | 5 | 4 | 5 | 5 | 5 |
1より小さいことはありません。もし、0ならばその問題には解答がないことになってしまいます。
そこのセルは、入れる数字がないからです。
もっとも、解答があるかどうかもチェックするソフトですから、
for(i=0;i<10;i++){
for(j=0;j<9;j++){
for(k=0;k<9;k++){
if(b[j][k]==i){
zy[gcn]=j;
zx[gcn]=k;
gcn++;
}
}
}
}
としておいて、
if(b[j][k]==i){正常でないと表示して、プログラムを止める処理をする。}
としてもよいわけです。
ただ、解が存在するかどうかは
if(s==0)dataGridView1[30,27]->Value=L"解答が存在しない";
if(s==0)dataGridView1[30,14]->Value=L"不適切な問題です。";
においてもチェックされているので、
for(i=1;i<10;i++){
for(j=0;j<9;j++){
for(k=0;k<9;k++){
if(b[j][k]==i){
zy[gcn]=j;
zx[gcn]=k;
gcn++;
}
}
}
}
でもよかったわけす。もちろん、解が存在しない場合は入力順構築以降の処理が無駄な処理ですから、
for(i=0;i<10;i++){
for(j=0;j<9;j++){
for(k=0;k<9;k++){
if(b[j][k]==i){
zy[gcn]=j;
zx[gcn]=k;
gcn++;
}
}
}
}
+ if(b[j][k]==i){正常でないと表示して、プログラムを止める処理をする。}
の方が、速く判断できるとは言えます。
しかし、解の存在しない問題は基本的には書籍やネット上には存在しません。
私が、調べた範囲では不適切な問題が掲載されている例は見たことがありません。
一応本の著者やサイト運営者が念入りにチェックしてから、問題として載せているようです。
したがって、ほとんどの問題では適切な問題ですから、
i=0から始める方が無駄というものです。
i=1から始める場合
* | 6 | 5 | 3 | 5 | 4 | * | 5 | 5 |
3 | 5 | * | * | 5 | * | 5 | 4 | 5 |
5 | 7 | 6 | 5 | 6 | 5 | 8 | 6 | 6 |
5 | 7 | 6 | 3 | 6 | * | 5 | 6 | 5 |
4 | 7 | * | 1 | 4 | 4 | 5 | 6 | * |
4 | 5 | 4 | 3 | * | * | 5 | * | 4 |
3 | 4 | 4 | * | 4 | 3 | 5 | * | * |
* | 7 | 5 | 5 | 5 | 4 | 5 | 5 | 6 |
* | 6 | 4 | * | 5 | 4 | 5 | 5 | 5 |
の場合であれば、
1 |
がその対象になり、このセルに入力順0が割り振られます。
i=2は存在しませんので、ここでは番号は割り振られません。
i=3は、6個存在しますが、
if(b[j][k]==i){
zy[gcn]=j;
zx[gcn]=k;
gcn++;
}
により、一番最初に発見された
3 |
に入力順1が割り振られます。そして、2番目に発見される
3 |
に入力順2が割り振られます。以下同様にして、残りの3のセルに番号が割り振られていき、
次に、4に対して順に番号が割り振られていきます。
このようにして
* | 48 | 21 | 1 | 22 | 7 | * | 23 | 24 |
2 | 25 | * | * | 26 | * | 27 | 8 | 28 |
29 | 59 | 49 | 30 | 50 | 31 | 63 | 51 | 52 |
32 | 60 | 53 | 3 | 54 | * | 33 | 55 | 34 |
9 | 61 | * | 0 | 10 | 11 | 35 | 56 | * |
12 | 36 | 13 | 4 | * | * | 37 | * | 14 |
5 | 15 | 16 | * | 17 | 6 | 38 | * | * |
* | 62 | 39 | 40 | 41 | 18 | 42 | 43 | 57 |
* | 58 | 19 | * | 44 | 20 | 45 | 46 | 47 |
と番号が割り振られていきます。
VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual
Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)