生活随笔
收集整理的這篇文章主要介紹了
简单数迷
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Description
很多人都曾經聽說過數獨,但你是否聽說過數謎(Karuro)呢?實際上,數謎是數獨的更大(且更難)的兄弟問題,而且在日本也是非常受歡迎的。
數謎問題和填字游戲類似,不過它要填的不是文字而是數字。數謎游戲的目標是用1-9填滿所有空格,且這些數字相加的和滿足相應的要求(或者稱為“提示”),且在同一欄(“欄”是指一些水平或者豎直的連續的空格,用于提示的格子不算空格)不能填重復的數字。當所有格子按要求被填滿后,這個數謎就看作被解決了。圖1和圖2是一個可能的數謎游戲示例。
當然,直接求解數謎問題的話會比較困難。所以現在我們需要解決的是一個更簡單的數謎問題。簡單數謎的形狀是一個(n+1)行乘(m+1)列的矩形。而簡單數謎也只有兩種要求,就是行要求和列要求,且分別處于第一行和第一列,其他格子則是空格,而左上角是忽略不計的。coolzzz同學愛好簡單數謎,他已經給一些簡單數謎填好了其中的一些空格。現在,他想尋求你的幫助,來幫他完成這些簡單數謎。如圖3所示,2和9是coolzzz同學已經填好的空格,圖4則是一個基于圖3 的一個可能的解答。
Input
輸入包含多組測試數據。第一行包含一個正整數T,表示測試數據數目。每組數據第一行是n(n<10)和m(m<10),表示數謎的形狀的大小。接下來一行有n個整數,是相應的行要求;然后一行是m個整數,是相應的列要求。接下來的n行每行有m個小于10的非負整數,0表示該空格還沒有被填數字,其他表示coolzzz同學已經填好的數字。輸入數據保證未填數字的空格不會超過16個。
Output
對于每組測試數據,輸出若干行。如果基于coolzzz已填的結果,該數謎只有一個解,則輸出該解;如果不止一個解,則輸出一行“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.
.
.
.
.
.
.
分析
一道簡單的爆搜題,和數獨比起來稍微復雜一點
我們每次填只關心當前行滿不滿足要求,最后結束的時候再來判斷是不是合法
.
.
.
.
.
.
程序:
#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;
}
轉載于:https://www.cnblogs.com/YYC-0304/p/11094937.html
總結
以上是生活随笔為你收集整理的简单数迷的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。