题目:
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.
![](http://acm.csu.edu.cn/upload/problem_attach/2017-07-22_61C396952C61B435/xTFS.png.pagespeed.ic.vqGZj3PWeK.png)
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
1 1 -/- -/5 4 3 2 -/- - 6 -/- -/- - -/- - 7/- - -/- -/- 2 8 -/- -/- - -/3 - -/- - -/- -/- 4 - -/- 8 7 6 5/- -/-
Sample Output
1 7/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 int
using 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;
}