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;}




原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 4岁宝宝不爱学习怎么办 4岁宝宝不爱写字怎么办 孩子调皮老师不让上学了怎么办 小学生写字握笔握出剪子来怎么办 儿子6岁不会写字怎么办 宝宝在幼儿园不说话怎么办 孩子上幼儿园不说话怎么办 幼儿写数字不写怎么办 小孩不吃饭怎么办 十个月 十个月小孩不爱吃饭怎么办 十个月的小孩不吃饭怎么办 家长要调幼儿园监控怎么办 自己带孩子婆婆生气怎么办 婆婆老是觉得我奶水不够怎么办 1岁小儿特别懒怎么办 17的孩子很懒怎么办 上大班的孩子不愿写字怎么办 快上中班的小朋友不爱学习怎么办 小学生两边肩膀不平应该怎么办 写字右肩膀疼是怎么办 开车久了肩膀疼怎么办 3岁宝宝撕书怎么办 孩子上幼儿园不爱写字怎么办 一年级小孩不爱做作业怎么办 小孩不愿多做作业怎么办 小孩一年级不自觉做作业怎么办 小孩会读不会写怎么办 好多字都不会写怎么办 写作业怎么办才能写快 五周宝宝爱玩不写字怎么办 爱玩手机的小孩怎么办? 一年级学生记不住生字怎么办 一年级小孩记不住生字怎么办 配镜度数高了怎么办 宝宝两岁半不肯坐马桶拉臭臭怎么办 儿子字写得不好 怎么办 小孩不听话不爱读书和写字怎么办 两岁宝宝不愿意穿衣服怎么办 做题粗心不认真怎么办 5岁宝宝不会写字怎么办 四岁宝宝不会写字怎么办