第21講 末項確定法
第2話 f1解答例と簡単な解説
void f1(int g){
if(s==100)return;
int i,j,h,wa,kk,kkk,m,sa;
if(g==n-1){
wa=0;
for(j=0;j<n-1;j++){
wa+=a1[j][j];
}
sa=n*(n-1)/2-wa;
if(sa<0 || sa>n-1)return;
if(cn1[sa]>n-1)return;
a1[y[g]][x[g]]=sa;
cn1[sa]++;
f1(g+1);
cn1[sa]--;
return;
}
if(y[g]==n-1 && x[g]==0){
wa=0;
for(j=0;j<n-1;j++){
wa+=a1[j][n-1-j];
}
sa=n*(n-1)/2-wa;
if(sa<0 || sa>n-1)return;
if(cn1[sa]>n-1)return;
a1[y[g]][x[g]]=sa;
cn1[sa]++;
f1(g+1);
cn1[sa]--;
return;
}
if(y[g]==0 && x[g]==n-2){
wa=0;
for(j=0;j<n-2;j++){
wa+=a1[0][j];
}
wa+=a1[0][n-1];
sa=n*(n-1)/2-wa;
if(sa<0 || sa>n-1)return;
if(cn1[sa]>n-1)return;
a1[y[g]][x[g]]=sa;
cn1[sa]++;
f1(g+1);
cn1[sa]--;
return;
}
if(y[g]==n-2 && x[g]==0){
wa=0;
for(j=0;j<n-2;j++){
wa+=a1[j][0];
}
wa+=a1[n-1][0];
sa=n*(n-1)/2-wa;
if(sa<0 || sa>n-1)return;
if(cn1[sa]>n-1)return;
a1[y[g]][x[g]]=sa;
cn1[sa]++;
f1(g+1);
cn1[sa]--;
return;
}
if(y[g]>0 && y[g]<n-1 && x[g]==n-1){
wa=0;
for(j=0;j<n-1;j++){
wa+=a1[y[g]][j];
}
sa=n*(n-1)/2-wa;
if(sa<0 || sa>n-1)return;
if(cn1[sa]>n-1)return;
a1[y[g]][x[g]]=sa;
cn1[sa]++;
f1(g+1);
cn1[sa]--;
return;
}
if(x[g]>0 && x[g]<n-1 && y[g]==n-1){
wa=0;
for(j=0;j<n-1;j++){
wa+=a1[j][x[g]];
}
sa=n*(n-1)/2-wa;
if(sa<0 || sa>n-1)return;
if(cn1[sa]>n-1)return;
a1[y[g]][x[g]]=sa;
cn1[sa]++;
if(g<n*n-1){
f1(g+1);
if(s==100)return;
}
else{
f2(0);
if(s==100)return;
}
cn1[sa]--;
return;
}
kk=rand()%n;
m=n/2;
for(i=0;i<n;i++){
kkk=(kk+i)%n;
a1[y[g]][x[g]]=kkk;
h=1;
cn1[kkk]++;
if(cn1[kkk]>n)h=0;
if(h==1)f1(g+1);
cn1[kkk]--;
}
}
(コピーペースト用
void f1(int g){
if(s==100)return;
int i,j,h,wa,kk,kkk,m,sa;
if(g==n-1){
wa=0;
for(j=0;j<n-1;j++){
wa+=a1[j][j];
}
sa=n*(n-1)/2-wa;
if(sa<0 || sa>n-1)return;
if(cn1[sa]>n-1)return;
a1[y[g]][x[g]]=sa;
cn1[sa]++;
f1(g+1);
cn1[sa]--;
return;
}
if(y[g]==n-1 && x[g]==0){
wa=0;
for(j=0;j<n-1;j++){
wa+=a1[j][n-1-j];
}
sa=n*(n-1)/2-wa;
if(sa<0 || sa>n-1)return;
if(cn1[sa]>n-1)return;
a1[y[g]][x[g]]=sa;
cn1[sa]++;
f1(g+1);
cn1[sa]--;
return;
}
if(y[g]==0 && x[g]==n-2){
wa=0;
for(j=0;j<n-2;j++){
wa+=a1[0][j];
}
wa+=a1[0][n-1];
sa=n*(n-1)/2-wa;
if(sa<0 || sa>n-1)return;
if(cn1[sa]>n-1)return;
a1[y[g]][x[g]]=sa;
cn1[sa]++;
f1(g+1);
cn1[sa]--;
return;
}
if(y[g]==n-2 && x[g]==0){
wa=0;
for(j=0;j<n-2;j++){
wa+=a1[j][0];
}
wa+=a1[n-1][0];
sa=n*(n-1)/2-wa;
if(sa<0 || sa>n-1)return;
if(cn1[sa]>n-1)return;
a1[y[g]][x[g]]=sa;
cn1[sa]++;
f1(g+1);
cn1[sa]--;
return;
}
if(y[g]>0 && y[g]<n-1 && x[g]==n-1){
wa=0;
for(j=0;j<n-1;j++){
wa+=a1[y[g]][j];
}
sa=n*(n-1)/2-wa;
if(sa<0 || sa>n-1)return;
if(cn1[sa]>n-1)return;
a1[y[g]][x[g]]=sa;
cn1[sa]++;
f1(g+1);
cn1[sa]--;
return;
}
if(x[g]>0 && x[g]<n-1 && y[g]==n-1){
wa=0;
for(j=0;j<n-1;j++){
wa+=a1[j][x[g]];
}
sa=n*(n-1)/2-wa;
if(sa<0 || sa>n-1)return;
if(cn1[sa]>n-1)return;
a1[y[g]][x[g]]=sa;
cn1[sa]++;
if(g<n*n-1){
f1(g+1);
if(s==100)return;
}
else{
f2(0);
if(s==100)return;
}
cn1[sa]--;
return;
}
kk=rand()%n;
m=n/2;
for(i=0;i<n;i++){
kkk=(kk+i)%n;
a1[y[g]][x[g]]=kkk;
h=1;
cn1[kkk]++;
if(cn1[kkk]>n)h=0;
if(h==1)f1(g+1);
cn1[kkk]--;
}
}
)
if(g==n-1){
wa=0;
for(j=0;j<n-1;j++){
wa+=a1[j][j];
}
sa=n*(n-1)/2-wa;
if(sa<0 || sa>n-1)return;
if(cn1[sa]>n-1)return;
a1[y[g]][x[g]]=sa;
cn1[sa]++;
f1(g+1);
cn1[sa]--;
return;
}
などの基本構造は同じです。
y | ||||||||||||
↓ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ← | x |
0 | 0 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 10 | ||
1 | 28 | 1 | 36 | 37 | 38 | 39 | 40 | 41 | 11 | 42 | ||
2 | 29 | 43 | 2 | 50 | 51 | 52 | 53 | 12 | 54 | 55 | ||
3 | 30 | 44 | 56 | 3 | 62 | 63 | 13 | 64 | 65 | 66 | ||
4 | 31 | 45 | 57 | 67 | 4 | 14 | 72 | 73 | 74 | 75 | ||
5 | 32 | 46 | 58 | 68 | 15 | 5 | 80 | 81 | 82 | 83 | ||
6 | 33 | 47 | 59 | 16 | 76 | 84 | 6 | 88 | 89 | 90 | ||
7 | 34 | 48 | 17 | 69 | 77 | 85 | 91 | 7 | 94 | 95 | ||
8 | 35 | 18 | 60 | 70 | 78 | 86 | 92 | 96 | 8 | 98 | ||
9 | 19 | 49 | 61 | 71 | 79 | 87 | 93 | 97 | 99 | 9 |
それは、基本的には水色以外の色のセルに来たときは、上の世界(g+1)の世界に上がるか、
下の世界(g−1)に戻るしかないのです。
ここではfor文で探索しなくていいわけです。
基本構造は同じですが、
各if文が少しずつ異なっている理由は、
色によって対角線を合計したり、行や列を合計したりしなければならないからです。
例えば、
09 |
のときには対角線
y | ||||||||||||
↓ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ← | x |
0 | 0 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 10 | ||
1 | 28 | 1 | 36 | 37 | 38 | 39 | 40 | 41 | 11 | 42 | ||
2 | 29 | 43 | 2 | 50 | 51 | 52 | 53 | 12 | 54 | 55 | ||
3 | 30 | 44 | 56 | 3 | 62 | 63 | 13 | 64 | 65 | 66 | ||
4 | 31 | 45 | 57 | 67 | 4 | 14 | 72 | 73 | 74 | 75 | ||
5 | 32 | 46 | 58 | 68 | 15 | 5 | 80 | 81 | 82 | 83 | ||
6 | 33 | 47 | 59 | 16 | 76 | 84 | 6 | 88 | 89 | 90 | ||
7 | 34 | 48 | 17 | 69 | 77 | 85 | 91 | 7 | 94 | 95 | ||
8 | 35 | 18 | 60 | 70 | 78 | 86 | 92 | 96 | 8 | 98 | ||
9 | 19 | 49 | 61 | 71 | 79 | 87 | 93 | 97 | 99 |
を合計しなければなりません。
注意しなけれいけないのは、
27 |
と
35 |
のセルのときです。
if(y[g]==0 && x[g]==n-2){
wa=0;
for(j=0;j<n-2;j++){
wa+=a1[0][j];
}
wa+=a1[0][n-1];
sa=n*(n-1)/2-wa;
if(sa<0 || sa>n-1)return;
if(cn1[sa]>n-1)return;
a1[y[g]][x[g]]=sa;
cn1[sa]++;
f1(g+1);
cn1[sa]--;
return;
}
if(y[g]==n-2 && x[g]==0){
wa=0;
for(j=0;j<n-2;j++){
wa+=a1[j][0];
}
wa+=a1[n-1][0];
sa=n*(n-1)/2-wa;
if(sa<0 || sa>n-1)return;
if(cn1[sa]>n-1)return;
a1[y[g]][x[g]]=sa;
cn1[sa]++;
f1(g+1);
cn1[sa]--;
return;
}
他の部分と合計の仕方が違うのは、
↓ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ← | x |
0 | 0 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 10 | ||
1 | 28 | 1 | 36 | 37 | 38 | 39 | 40 | 41 | 11 | 42 | ||
2 | 29 | 43 | 2 | 50 | 51 | 52 | 53 | 12 | 54 | 55 | ||
3 | 30 | 44 | 56 | 3 | 62 | 63 | 13 | 64 | 65 | 66 | ||
4 | 31 | 45 | 57 | 67 | 4 | 14 | 72 | 73 | 74 | 75 | ||
5 | 32 | 46 | 58 | 68 | 15 | 5 | 80 | 81 | 82 | 83 | ||
6 | 33 | 47 | 59 | 16 | 76 | 84 | 6 | 88 | 89 | 90 | ||
7 | 34 | 48 | 17 | 69 | 77 | 85 | 91 | 7 | 94 | 95 | ||
8 | 35 | 18 | 60 | 70 | 78 | 86 | 92 | 96 | 8 | 98 | ||
9 | 19 | 49 | 61 | 71 | 79 | 87 | 93 | 97 | 99 | 9 |
y | ||||||||||||
↓ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ← | x |
0 | 0 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 10 | ||
1 | 28 | 1 | 36 | 37 | 38 | 39 | 40 | 41 | 11 | 42 | ||
2 | 29 | 43 | 2 | 50 | 51 | 52 | 53 | 12 | 54 | 55 | ||
3 | 30 | 44 | 56 | 3 | 62 | 63 | 13 | 64 | 65 | 66 | ||
4 | 31 | 45 | 57 | 67 | 4 | 14 | 72 | 73 | 74 | 75 | ||
5 | 32 | 46 | 58 | 68 | 15 | 5 | 80 | 81 | 82 | 83 | ||
6 | 33 | 47 | 59 | 16 | 76 | 84 | 6 | 88 | 89 | 90 | ||
7 | 34 | 48 | 17 | 69 | 77 | 85 | 91 | 7 | 94 | 95 | ||
8 | 35 | 18 | 60 | 70 | 78 | 86 | 92 | 96 | 8 | 98 | ||
9 | 19 | 49 | 61 | 71 | 79 | 87 | 93 | 97 | 99 | 9 |
19 |
の存在です。
ここはすれに数字が埋まっています。
ですから
35 |
の前までと
19 |
を加えなければならないです。
さて、最後だけ
if(x[g]>0 && x[g]<n-1 && y[g]==n-1){
wa=0;
for(j=0;j<n-1;j++){
wa+=a1[j][x[g]];
}
sa=n*(n-1)/2-wa;
if(sa<0 || sa>n-1)return;
if(cn1[sa]>n-1)return;
a1[y[g]][x[g]]=sa;
cn1[sa]++;
if(g<n*n-1){
f1(g+1);
if(s==100)return;
}
else{
f2(0);
if(s==100)return;
}
cn1[sa]--;
return;
}
他とはかなり違っています。
y | ||||||||||||
↓ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ← | x |
0 | 0 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 10 | ||
1 | 28 | 1 | 36 | 37 | 38 | 39 | 40 | 41 | 11 | 42 | ||
2 | 29 | 43 | 2 | 50 | 51 | 52 | 53 | 12 | 54 | 55 | ||
3 | 30 | 44 | 56 | 3 | 62 | 63 | 13 | 64 | 65 | 66 | ||
4 | 31 | 45 | 57 | 67 | 4 | 14 | 72 | 73 | 74 | 75 | ||
5 | 32 | 46 | 58 | 68 | 15 | 5 | 80 | 81 | 82 | 83 | ||
6 | 33 | 47 | 59 | 16 | 76 | 84 | 6 | 88 | 89 | 90 | ||
7 | 34 | 48 | 17 | 69 | 77 | 85 | 91 | 7 | 94 | 95 | ||
8 | 35 | 18 | 60 | 70 | 78 | 86 | 92 | 96 | 8 | 98 | ||
9 | 19 | 49 | 61 | 71 | 79 | 87 | 93 | 97 | 99 | 9 |
理由は、茶色セルの中に
y | ||||||||||||
↓ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ← | x |
0 | 0 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 10 | ||
1 | 28 | 1 | 36 | 37 | 38 | 39 | 40 | 41 | 11 | 42 | ||
2 | 29 | 43 | 2 | 50 | 51 | 52 | 53 | 12 | 54 | 55 | ||
3 | 30 | 44 | 56 | 3 | 62 | 63 | 13 | 64 | 65 | 66 | ||
4 | 31 | 45 | 57 | 67 | 4 | 14 | 72 | 73 | 74 | 75 | ||
5 | 32 | 46 | 58 | 68 | 15 | 5 | 80 | 81 | 82 | 83 | ||
6 | 33 | 47 | 59 | 16 | 76 | 84 | 6 | 88 | 89 | 90 | ||
7 | 34 | 48 | 17 | 69 | 77 | 85 | 91 | 7 | 94 | 95 | ||
8 | 35 | 18 | 60 | 70 | 78 | 86 | 92 | 96 | 8 | 98 | ||
9 | 19 | 49 | 61 | 71 | 79 | 87 | 93 | 97 | 99 | 9 |
最後のセル
99 |
が存在するからです。
ここまで来たら、一般種の1個目は完成で、
2個目の種の製作関数f2に進まなければならないので、
ここだけ少し変わっているのです。
では皆さん、f1を参考にしてf2を考えましょう。
結構難しいですよ。
第21講第1話へ 第21講第3話へ
VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual
Basic入門基礎講座