【問題】 填字游戲
問題描述:在3×3個方格的方陣中要填入數(shù)字1到n(n≥10)內(nèi)的某9個數(shù)字,每個方格填一個整數(shù),似的所有相鄰兩個方格內(nèi)的兩個整數(shù)之和為質(zhì)數(shù)。試求出所有滿足這個要求的各種數(shù)字填法。
可用試探發(fā)找到問題的解,即從第一個方格開始,為當(dāng)前方格尋找一個合理的整數(shù)填入,并在當(dāng)前位置正確填入后,為下一方格尋找可填入的合理整數(shù)。如不能為當(dāng)前方格找到一個合理的可填證書,就要回退到前一方格,調(diào)整前一方格的填入數(shù)。當(dāng)?shù)诰艂€方格也填入合理的整數(shù)后,就找到了一個解,將該解輸出,并調(diào)整第九個的填入的整數(shù),尋找下一個解。
為找到一個滿足要求的9個數(shù)的填法,從還未填一個數(shù)開始,按某種順序(如從小到大的順序)每次在當(dāng)前位置填入一個整數(shù),然后檢查當(dāng)前填入的整數(shù)是否能滿足要求。在滿足要求的情況下,繼續(xù)用同樣的方法為下一方格填入整數(shù)。如果最近填入的整數(shù)不能滿足要求,就改變填入的整數(shù)。如對當(dāng)前方格試盡所有可能的整數(shù),都不能滿足要求,就得回退到前一方格,并調(diào)整前一方格填入的整數(shù)。如此重復(fù)執(zhí)行擴展、檢查或調(diào)整、檢查,直到找到一個滿足問題要求的解,將解輸出。
回溯法找一個解的算法:
{ int m=0,ok=1;
int n=8;
do{
if (ok) 擴展;
else 調(diào)整;
ok=檢查前m個整數(shù)填放的合理性;
} while ((!ok||m!=n)&&(m!=0))
if (m!=0) 輸出解;
else 輸出無解報告;
}
如果程序要找全部解,則在將找到的解輸出后,應(yīng)繼續(xù)調(diào)整最后位置上填放的整數(shù),試圖去找下一個解。相應(yīng)的算法如下:
回溯法找全部解的算法:
{ int m=0,ok=1;
int n=8;
do{
if (ok)
{ if (m==n)
{ 輸出解;
調(diào)整;
}
else 擴展;
}
else 調(diào)整;
ok=檢查前m個整數(shù)填放的合理性;
} while (m!=0);
}
為了確保程序能夠終止,調(diào)整時必須保證曾被放棄過的填數(shù)序列不會再次實驗,即要求按某種有許模型生成填數(shù)序列。給解的候選者設(shè)定一個被檢驗的順序,按這個順序逐一形成候選者并檢驗。從小到大或從大到小,都是可以采用的方法。如擴展時,先在新位置填入整數(shù)1,調(diào)整時,找當(dāng)前候選解中下一個還未被使用過的整數(shù)。將上述擴展、調(diào)整、檢驗都編寫成程序,細節(jié)見以下找全部解的程序。
【程序】
# include
# define n 12
void write(int a[ ])
{ int i,j;
for (i=0;i<3;i++)
{ for (j=0;j<3;j++)
printf(“%3d”,a[3*i+j]);
printf(“\n”);
}
scanf(“%*c”);
}
int b[n+1];
int a[10];
int isprime(int m)
{ int i;
int primes[ ]={2,3,5,7,11,17,19,23,29,-1};
if (m==1||m%2=0) return 0;
for (i=0;primes[i]>0;i++)
if (m==primes[i]) return 1;
for (i=3;i*i<=m;)
{ if (m%i==0) return 0;
i+=2;
}
return 1;
}
問題描述:在3×3個方格的方陣中要填入數(shù)字1到n(n≥10)內(nèi)的某9個數(shù)字,每個方格填一個整數(shù),似的所有相鄰兩個方格內(nèi)的兩個整數(shù)之和為質(zhì)數(shù)。試求出所有滿足這個要求的各種數(shù)字填法。
可用試探發(fā)找到問題的解,即從第一個方格開始,為當(dāng)前方格尋找一個合理的整數(shù)填入,并在當(dāng)前位置正確填入后,為下一方格尋找可填入的合理整數(shù)。如不能為當(dāng)前方格找到一個合理的可填證書,就要回退到前一方格,調(diào)整前一方格的填入數(shù)。當(dāng)?shù)诰艂€方格也填入合理的整數(shù)后,就找到了一個解,將該解輸出,并調(diào)整第九個的填入的整數(shù),尋找下一個解。
為找到一個滿足要求的9個數(shù)的填法,從還未填一個數(shù)開始,按某種順序(如從小到大的順序)每次在當(dāng)前位置填入一個整數(shù),然后檢查當(dāng)前填入的整數(shù)是否能滿足要求。在滿足要求的情況下,繼續(xù)用同樣的方法為下一方格填入整數(shù)。如果最近填入的整數(shù)不能滿足要求,就改變填入的整數(shù)。如對當(dāng)前方格試盡所有可能的整數(shù),都不能滿足要求,就得回退到前一方格,并調(diào)整前一方格填入的整數(shù)。如此重復(fù)執(zhí)行擴展、檢查或調(diào)整、檢查,直到找到一個滿足問題要求的解,將解輸出。
回溯法找一個解的算法:
{ int m=0,ok=1;
int n=8;
do{
if (ok) 擴展;
else 調(diào)整;
ok=檢查前m個整數(shù)填放的合理性;
} while ((!ok||m!=n)&&(m!=0))
if (m!=0) 輸出解;
else 輸出無解報告;
}
如果程序要找全部解,則在將找到的解輸出后,應(yīng)繼續(xù)調(diào)整最后位置上填放的整數(shù),試圖去找下一個解。相應(yīng)的算法如下:
回溯法找全部解的算法:
{ int m=0,ok=1;
int n=8;
do{
if (ok)
{ if (m==n)
{ 輸出解;
調(diào)整;
}
else 擴展;
}
else 調(diào)整;
ok=檢查前m個整數(shù)填放的合理性;
} while (m!=0);
}
為了確保程序能夠終止,調(diào)整時必須保證曾被放棄過的填數(shù)序列不會再次實驗,即要求按某種有許模型生成填數(shù)序列。給解的候選者設(shè)定一個被檢驗的順序,按這個順序逐一形成候選者并檢驗。從小到大或從大到小,都是可以采用的方法。如擴展時,先在新位置填入整數(shù)1,調(diào)整時,找當(dāng)前候選解中下一個還未被使用過的整數(shù)。將上述擴展、調(diào)整、檢驗都編寫成程序,細節(jié)見以下找全部解的程序。
【程序】
# include
# define n 12
void write(int a[ ])
{ int i,j;
for (i=0;i<3;i++)
{ for (j=0;j<3;j++)
printf(“%3d”,a[3*i+j]);
printf(“\n”);
}
scanf(“%*c”);
}
int b[n+1];
int a[10];
int isprime(int m)
{ int i;
int primes[ ]={2,3,5,7,11,17,19,23,29,-1};
if (m==1||m%2=0) return 0;
for (i=0;primes[i]>0;i++)
if (m==primes[i]) return 1;
for (i=3;i*i<=m;)
{ if (m%i==0) return 0;
i+=2;
}
return 1;
}