CSU 1969 TFSudoku 特殊数独
来源:互联网 发布:淘宝。eve技能注入 编辑:程序博客网 时间:2024/06/10 05:37
题目:
Description
At some point or another, most computer science students have written a standard Sudoku solving program. A slight twist has been added to standard Sudoku to make it a bit more challenging.
Digits from 1 to 9 are entered in a 6x6 grid so that no number is repeated in any row, column or 3x2 outlined region as shown below. Some squares in the grid are split by a slash and need 2 digits entered in them. The smaller number always goes above the slash.
For this problem, you will write a program that takes as input an incomplete puzzle grid and outputs the puzzle solution grid.
Input
The first line of input contains a single decimal integer P, (1 ≤ P ≤ 100), which is the number of data sets that follow. Each data set should be processed identically and independently.
Each data set consists of 7 lines of input. The first line of the data set contains the data set number, K. The remaining 6 lines represent an incomplete Tight-Fit Sudoku grid, each line has 6 data elements, separated by spaces. A data element can be a digit (1-9), a dash ('-
') for a blank square or two of these separated by a slash ('/
')
Output
For each data set there are 7 lines of output. The first output line consists of the data set number, K. The following 6 lines of output show the solution grid for the corresponding input data set. Each line will have 6 data elements, separated by spaces. A data element can be a digit (1-9), or 2 digits separated by a slash (‘/
’).
Sample Input
11-/- -/5 4 3 2 -/-- 6 -/- -/- - -/-- 7/- - -/- -/- 28 -/- -/- - -/3 --/- - -/- -/- 4 --/- 8 7 6 5/- -/-
Sample Output
17/9 1/5 4 3 2 6/8 3 6 2/8 1/9 7 4/5 1 7/9 3 4/5 6/8 2 8 2/4 5/6 7 1/3 9 5/6 3 1/9 2/8 4 7 2/4 8 7 6 5/9 1/3
一个加了特殊规则的数独,6x6的格子中会有斜杠出现,出现斜杠的格子斜杠上下一起要填2个数字,且上面的必须比下面小。
直接枚举不知道能不能过,我采用模拟人做数独的方法,先使用排除法,把能确定的数字都填上,没有可以确定的数字之后再选择可能性比较少的格子进行假设。
#include <iostream>#include <stdio.h>#include <string.h>#include <stack>#include <math.h>#include <algorithm>#include <map>#include <string>#define INF 0x3f3f3f3f#define MS(x,y) memset(x, y, sizeof(x))#define MOD 1000000007#define LL long long intusing namespace std;struct node{ int x,y;}z[10][10];int f[10][10][2][10];//前2维表示第几行第几列。第3维表示格子的上下。第4维表示那些数字不能填,0记录剩余可填的数字数bool xie[10][10];//记录有斜杠的格子int T;char s[5];void show(){ //printf("*****************************\n"); for(int i=0;i<6;++i) { for(int j=0;j<6;++j) { if(xie[i][j]) { printf("%d/%d ", z[i][j].x, z[i][j].y); } else printf("%d ", z[i][j].x); } printf("\n"); } //printf("*****************************\n");}void tian(int a, int b, int x, int y)//填数字,并且把周围的格子出现这个数字的可能性去掉,x表示斜杠上的数字,y表示斜杠下的数字{ int xoff = b/3*3; int yoff = a/2*2; if(x != 0) { z[a][b].x = x; for(int i=0;i<6;++i) { if(f[a][i][0][x] == 0) --f[a][i][0][0]; f[a][i][0][x] = 1; if(f[i][b][0][x] == 0) --f[i][b][0][0]; f[i][b][0][x] = 1; if(f[a][i][1][x] == 0) --f[a][i][1][0]; f[a][i][1][x] = 1; if(f[i][b][1][x] == 0) --f[i][b][1][0]; f[i][b][1][x] = 1; } for(int i=0;i<2;++i) { for(int j=0;j<3;++j) { if(f[yoff+i][xoff+j][0][x] == 0) --f[yoff+i][xoff+j][0][0]; f[yoff+i][xoff+j][0][x] = 1; if(f[yoff+i][xoff+j][1][x] == 0) --f[yoff+i][xoff+j][1][0]; f[yoff+i][xoff+j][1][x] = 1; } } if(xie[a][b]) { for(int i=x-1;i>0;--i) { if(f[a][b][1][i] == 0) --f[a][b][1][0]; f[a][b][1][i] = 1; } } } if(y != 0 && x != y) { z[a][b].y = y; for(int i=0;i<6;++i) { if(f[a][i][0][y] == 0) --f[a][i][0][0]; f[a][i][0][y] = 1; if(f[i][b][0][y] == 0) --f[i][b][0][0]; f[i][b][0][y] = 1; if(f[a][i][1][y] == 0) --f[a][i][1][0]; f[a][i][1][y] = 1; if(f[i][b][1][y] == 0) --f[i][b][1][0]; f[i][b][1][y] = 1; } for(int i=0;i<2;++i) { for(int j=0;j<3;++j) { if(f[yoff+i][xoff+j][0][y] == 0) --f[yoff+i][xoff+j][0][0]; f[yoff+i][xoff+j][0][y] = 1; if(f[yoff+i][xoff+j][1][y] == 0) --f[yoff+i][xoff+j][1][0]; f[yoff+i][xoff+j][1][y] = 1; } } if(xie[a][b]) { for(int i=y+1;i<10;++i) { if(f[a][b][0][i] == 0) --f[a][b][0][0]; f[a][b][0][i] = 1; } } }}bool judge()//判断是否得出答案{ for(int i=0;i<6;++i) { for(int j=0;j<6;++j) { if(xie[i][j]) { if(z[i][j].x == 0 || z[i][j].y == 0) return false; } else { if(z[i][j].x == 0) return false; } } } return true;}bool solve(){ while(1) { int x=0,y=0,MIN = 9,ff = 0; bool istian = false; bool maodun = false; for(int i=0;i<6;++i) { for(int j=0;j<6;++j) { if(xie[i][j]) { if(z[i][j].x == 0) { if(f[i][j][0][0] == 0) { maodun = true; //printf("*****(%d,%d)矛盾\n", i, j); break; } else if(f[i][j][0][0] == 1) { for(int ii=1;ii<10;++ii) { if(f[i][j][0][ii] == 0) { tian(i,j,ii,0); istian = true; } } } else if(f[i][j][0][0] > 1) { if(f[i][j][0][0] < MIN) { MIN = f[i][j][0][0]; x = j; y = i; ff = 0; } } } if(z[i][j].y == 0) { if(f[i][j][1][0] == 0) { maodun = true; //printf("*****(%d,%d)矛盾\n", i, j); break; } else if(f[i][j][1][0] == 1) { for(int ii=1;ii<10;++ii) { if(f[i][j][1][ii] == 0) { tian(i,j,0,ii); istian = true; } } } else if(f[i][j][1][0] > 1) { if(f[i][j][1][0] < MIN) { MIN = f[i][j][1][0]; x = j; y = i; ff = 1; } } } } else { if(z[i][j].x == 0) { if(f[i][j][0][0] == 0) { maodun = true; //printf("*****(%d,%d)矛盾\n", i, j); break; } else if(f[i][j][0][0] == 1) { for(int ii=1;ii<10;++ii) { if(f[i][j][0][ii] == 0) { tian(i,j,ii,ii); istian = true; } } } else if(f[i][j][0][0] > 1) { if(f[i][j][0][0] < MIN) { MIN = f[i][j][0][0]; x = j; y = i; ff = 0; } } } } } if(maodun) break; } //show(); if(maodun) { //printf("返回\n"); return false; } if(!istian) { if(judge()) return true; node tz[10][10]; int tf[10][10][2][10]; for(int i=0;i<6;++i) { for(int j=0;j<6;++j) { tz[i][j] = z[i][j]; for(int k=0;k<2;++k) { for(int m=0;m<10;++m) { tf[i][j][k][m] = f[i][j][k][m]; } } } } for(int ii=1;ii<10;++ii) { if(f[y][x][ff][ii] == 0) { //printf("*************假设(%d,%d,%d,%d)\n", y, x, ff, ii); if(y == 3 && x == 1 && ff == 0 && ii == 2) ii = 2; if(ff == 0) tian(y,x,ii,0); else tian(y,x,0,ii); if(solve()) return true; for(int i=0;i<6;++i) { for(int j=0;j<6;++j) { z[i][j] = tz[i][j]; for(int k=0;k<2;++k) { for(int m=0;m<10;++m) { f[i][j][k][m] = tf[i][j][k][m]; } } } } } } return false; } } return true;}int main(){ scanf("%d", &T); while(T--) { int CASE; scanf("%d", &CASE); MS(z, 0); MS(f, 0); MS(xie, 0); for(int i=0;i<6;++i) { for(int j=0;j<6;++j) { f[i][j][0][0] = f[i][j][1][0] = 9; } } for(int i=0;i<6;++i) { for(int j=0;j<6;++j) { scanf("%s", s); int len = strlen(s); if(len == 1 && s[0] != '-') { tian(i,j,s[0]-'0',s[0]-'0'); } if(len == 3) { xie[i][j] = 1; tian(i,j,s[0]=='-'?0:s[0]-'0',s[2]=='-'?0:s[2]-'0'); } } int t = 0; } //show(); solve(); printf("%d\n", CASE); show(); } return 0;}
- CSU 1969 TFSudoku 特殊数独
- 数独
- 数独
- 数独
- 数独
- 数独
- 数独
- 数独
- 数独
- 数独
- 数独
- 数独
- 数独
- 数独
- 数独
- 数独
- 数独
- 数独
- [PAT乙级]1046. 划拳(15)
- 10562
- layui框架详细分析系列之框架主体组织结构
- Eclipse中项目切换SVN路径
- python读取并写入mat文件
- CSU 1969 TFSudoku 特殊数独
- BT1120接口及协议
- Token原理以及应用
- nodeValue和value的区别
- css小技巧总结
- android 布局 中两个空格宽度与一个汉字宽度问题
- React Native入门(七)之列表组件的使用(2)关于FlatList的一切
- java主函数参数传递args
- 七月英语总结