题目描述:都玩过这个游戏,同行同列不能出现相同的数字,同一个9格子中也不能相同的出现。
解决:dfs+回溯
把每行每列不能用的元素检出来,在搜索的时候看每9个格子的情况,用check函数, 用两个vis数组存放行的信息和列的信息
#include <iostream> #include <cstdio> using namespace std; int map[10][10]; bool vis1[10][10],vis2[10][10]; bool found; bool check(int x,int y,int val) {//检测每9个格子中的数是否重复 for(int i=(x-1)/3*3+1;i<=(x-1)/3*3+3;i++) for(int j=(y-1)/3*3+1;j<=(y-1)/3*3+3;j++) if(map[i][j]==val)return false; return true; } void show() { for(int i=1;i<=9;i++) { for(int j=1;j<=9;j++)printf("%d",map[i][j]); printf("\n"); } } void dfs(int x,int y) { if(found)return; //返回条件是x=9并且y=10 if(x==9 && y==10){found=true; show();return; } //若y=10,进行下一行 if(y==10)dfs(x+1,1); //下标为x,y的元素是否已经有了数字,有数字的话进行下一个, //没有的话填写数,并回溯 if(map[x][y])dfs(x,y+1); else { for(int i=1;i<=9;i++) { if(!vis1[x][i] && !vis2[y][i] && check(x,y,i) ) { if(y<=9) { vis1[x][i]=1; vis2[y][i]=1; map[x][y]=i; dfs(x,y+1); vis1[x][i]=0; vis2[y][i]=0; map[x][y]=0; } } } } } int main() { int icase; scanf("%d",&icase); while(icase--) { char c; found=false; memset(vis1,0,sizeof(vis1)); memset(vis2,0,sizeof(vis2)); //预处理 for(int i=1;i<=9;i++) { getchar(); for(int j=1;j<=9;j++) { scanf("%c",&c); map[i][j]=c-'0'; if(map[i][j]) {//vis1数组存放的是行中是否使用,vis2存放列中某个数是否使用 vis1[i][map[i][j]]=1; vis2[j][map[i][j]]=1; } } } //下标从1开始 dfs(1,1); } system("pause"); return 0; }