生活随笔
收集整理的這篇文章主要介紹了
简单数迷
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
Description
很多人都曾經(jīng)聽說過數(shù)獨(dú),但你是否聽說過數(shù)謎(Karuro)呢?實(shí)際上,數(shù)謎是數(shù)獨(dú)的更大(且更難)的兄弟問題,而且在日本也是非常受歡迎的。
數(shù)謎問題和填字游戲類似,不過它要填的不是文字而是數(shù)字。數(shù)謎游戲的目標(biāo)是用1-9填滿所有空格,且這些數(shù)字相加的和滿足相應(yīng)的要求(或者稱為“提示”),且在同一欄(“欄”是指一些水平或者豎直的連續(xù)的空格,用于提示的格子不算空格)不能填重復(fù)的數(shù)字。當(dāng)所有格子按要求被填滿后,這個數(shù)謎就看作被解決了。圖1和圖2是一個可能的數(shù)謎游戲示例。
當(dāng)然,直接求解數(shù)謎問題的話會比較困難。所以現(xiàn)在我們需要解決的是一個更簡單的數(shù)謎問題。簡單數(shù)謎的形狀是一個(n+1)行乘(m+1)列的矩形。而簡單數(shù)謎也只有兩種要求,就是行要求和列要求,且分別處于第一行和第一列,其他格子則是空格,而左上角是忽略不計(jì)的。coolzzz同學(xué)愛好簡單數(shù)謎,他已經(jīng)給一些簡單數(shù)謎填好了其中的一些空格?,F(xiàn)在,他想尋求你的幫助,來幫他完成這些簡單數(shù)謎。如圖3所示,2和9是coolzzz同學(xué)已經(jīng)填好的空格,圖4則是一個基于圖3 的一個可能的解答。
Input
輸入包含多組測試數(shù)據(jù)。第一行包含一個正整數(shù)T,表示測試數(shù)據(jù)數(shù)目。每組數(shù)據(jù)第一行是n(n<10)和m(m<10),表示數(shù)謎的形狀的大小。接下來一行有n個整數(shù),是相應(yīng)的行要求;然后一行是m個整數(shù),是相應(yīng)的列要求。接下來的n行每行有m個小于10的非負(fù)整數(shù),0表示該空格還沒有被填數(shù)字,其他表示coolzzz同學(xué)已經(jīng)填好的數(shù)字。輸入數(shù)據(jù)保證未填數(shù)字的空格不會超過16個。
Output
對于每組測試數(shù)據(jù),輸出若干行。如果基于coolzzz已填的結(jié)果,該數(shù)謎只有一個解,則輸出該解;如果不止一個解,則輸出一行“Not unique.”;如果沒有解,則輸出一行“No answer.”。
Sample Input
3
3 3
6 6 6
6 6 6
0 0 0
0 3 0
0 0 0
2 3
10 17
5 16 6
2 0 0
0 9 0
2 2
3 5
4 4
0 0
0 0
Sample Output
Not unique.
2 7 1
3 9 5
No answer.
.
.
.
.
.
.
分析
一道簡單的爆搜題,和數(shù)獨(dú)比起來稍微復(fù)雜一點(diǎn)
我們每次填只關(guān)心當(dāng)前行滿不滿足要求,最后結(jié)束的時候再來判斷是不是合法
.
.
.
.
.
.
程序:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
int n,m;
int xx[15],yy[15],mp[15][15],sum1[15],sum2[15],ans[15][15],sum;
bool fx[15][15],fy[15][15];void dfs(int x,int y)
{if (sum>1) return;if (x==n+1){bool bz=false;for (int i=1;i<=m;i++)if (yy[i]!=sum2[i]){ bz=true;break;}if (bz==false){sum++;if (sum==1){for (int i=1;i<=n;i++)for(int j=1;j<=m;j++)ans[i][j]=mp[i][j];}}return;} else if (y==m+1){if (xx[x]==sum1[x]) dfs(x+1,1);} elseif (mp[x][y]!=0) dfs(x,y+1); else{for (int i=1;i<=9;i++)if (fx[x][i]&&fy[y][i]&&sum1[x]+i<=xx[x]&&sum2[y]+i<=yy[y]){sum1[x]+=i;sum2[y]+=i;mp[x][y]=i;fx[x][i]=fy[y][i]=false;dfs(x,y+1);sum1[x]-=i;sum2[y]-=i;mp[x][y]=0;fx[x][i]=fy[y][i]=true;}}
}int main()
{freopen("kakuro.in","r",stdin);freopen("kakuro.out","w",stdout);int t;scanf("%d",&t);while (t--){memset(sum1,0,sizeof(sum1));memset(sum2,0,sizeof(sum2));memset(fx,true,sizeof(fx));memset(fy,true,sizeof(fy));scanf("%d%d",&n,&m);for (int i=1;i<=n;i++)scanf("%d",&xx[i]);for (int i=1;i<=m;i++)scanf("%d",&yy[i]);for (int i=1;i<=n;i++)for (int j=1;j<=m;j++){scanf("%d",&mp[i][j]);fx[i][mp[i][j]]=false;fy[j][mp[i][j]]=false;sum1[i]+=mp[i][j];sum2[j]+=mp[i][j];}sum=0;dfs(1,1);if (sum>1) printf("Not unique.\n"); elseif (sum==0) printf("No answer.\n"); else {for(int i=1;i<=n;i++){for (int j=1;j<=m;j++)printf("%d ",ans[i][j]);printf("\n"); }}}fclose(stdin);fclose(stdout);return 0;
}
轉(zhuǎn)載于:https://www.cnblogs.com/YYC-0304/p/11094937.html
總結(jié)
以上是生活随笔為你收集整理的简单数迷的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。