数独填充问题

题目描述

给出一个4*4的矩阵,在矩阵中填入数字1,2,3,4,使得每行、每列的数字不重复,而且左上角、右上角、左下角、右下角的2*2小矩阵的4个数字不重复。

输入描述

输入包含多组测试数据。第一行为一个整数T(1<=T<=10),表示有T组测试数据。

第二行开始为T组测试数据。

输出描述

首先输出一行“Case #x:”,x表示第i组测试数据。

然后输出填充的4*4矩阵。每组测试数据之间输出一个空行。

输入样例

2
****
2341
4123
3214

*243
*312
*421
*134

输出样例

Case #1:
1432
2341
4123
3214

Case #2:
1243
4312
3421
2134

提示


AC代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

char mat[4][4];  ///存储4*4的数字矩阵
int cnt;
struct point{
   int row, col;
} p[17];

int try(int pos)
{
    if(pos > cnt) return 1;
    int row, col;
    row = p[pos].row;
    col = p[pos].col;
    int vis[5]; ///数字1-4是否已填写
    memset(vis, 0, sizeof(vis));
    int i;
    for(i=0; i<4; i++) ///检查(row,col)安全性
    {
        if(mat[row][i] != '*') vis[mat[row][i]-'0'] = 1;
        if(mat[i][col] != '*') vis[mat[i][col]-'0'] = 1;
    }
    if(mat[row^1][col^1] != '*') vis[mat[row^1][col^1]-'0'] = 1;
    int x;
    for(x=1; x<=4; x++){  ///依次尝试1,2,3,4的数字
        if(!vis[x]){
            mat[row][col] = x + '0';
            if(try(pos+1)) return 1;  ///成功就返回,否则回溯
            mat[row][col] = '*';
        }
    }
    return 0;
}


int main()
{
  // freopen("mat4.in", "r", stdin);
   // freopen("mat4.out", "w", stdout);
    int t, k = 0;
    scanf("%d", &t);
    while(t--)
    {
        cnt = 0;
        ///读入4*4矩阵
        int i, j;
        char ch[5];  ///读入一行字符
        for(i=0; i<4; i++){
            scanf("%s", ch);///读入一行字符存入数组ch[]
            for(j=0; j<4; j++){
                mat[i][j] = ch[j];
                if(mat[i][j] == '*'){
                    cnt++;
                    p[cnt].row = i;
                    p[cnt].col = j;
                  ///  cnt++; 放到这里,p[]从0开始就错了
                }
            }
        }
        try(1); ///try(0);

        ///打印结果
        printf("Case #%d:\n", ++k);
        for(i=0; i<4; i++){
            for(j=0; j<4; j++)
                printf("%c", mat[i][j]);
            printf("\n");
        }
    }
    return 0;
}


  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值