BZOJ 3109 CQOI 2013 新数独

75 篇文章 1 订阅
37 篇文章 0 订阅

暴力大法好。

读入挺麻烦?

3s好慢QAQ

强行爆搜即可,及时判断行列以及小方格的数字是否使用和大于小于就可以过了。

代码比较丑。

#include <cstdio>
#include <cstdlib>
#define rep(i,j,k) for(int i=j;i<k;i++)
using namespace std;
const int block[9][9] = {
    {1,1,1,2,2,2,3,3,3},
    {1,1,1,2,2,2,3,3,3},
    {1,1,1,2,2,2,3,3,3},
    {4,4,4,5,5,5,6,6,6},
    {4,4,4,5,5,5,6,6,6},
    {4,4,4,5,5,5,6,6,6},
    {7,7,7,8,8,8,9,9,9},
    {7,7,7,8,8,8,9,9,9},
    {7,7,7,8,8,8,9,9,9}
};
typedef bool (*cmp)(int, int);
struct Comparator { cmp up, left; } map[10][10];
bool cmp_less(int a, int b) { return a < b; }
bool cmp_greater(int a, int b) { return a > b; }
int vis_col[10][10], vis_row[10][10], vis_block[10][10], ans[10][10];

void out() {
    rep(i,0,9) {
        rep(j,0,8) printf("%d ",ans[i][j]);
        printf("%d\n", ans[i][8]);
    }
}

bool check(int x, int y, int i) {
    if (map[x][y].left != 0 && !map[x][y].left(i,ans[x][y-1])) return 0;
    if (map[x][y].up != 0 && !map[x][y].up(i,ans[x-1][y])) return 0;
    return 1;
}

void dfs(int x, int y) {
    if (x == 9) out(), exit(0);
    rep(i,1,10)
        if (!vis_col[x][i] && !vis_row[y][i] && !vis_block[block[x][y]][i])
            if (check(x,y,i)) {
                ans[x][y] = i;
                vis_col[x][i] = vis_row[y][i] = vis_block[block[x][y]][i] = 1;
                if (y == 8) dfs(x + 1, 0);
                else dfs(x, y + 1);
                vis_col[x][i] = vis_row[y][i] = vis_block[block[x][y]][i] = 0;
            }
}

char valid_char() {
    char ch = getchar();
    while (ch == ' ' || ch == '\n' || ch == '\r') ch = getchar();
    return ch;
}

int main() {
    int h = 0, l;
    rep(k,0,3) rep(j,0,3) {
        l = 0;
        rep(i,0,3) {
            map[h][++l].left = valid_char() == '>' ? cmp_less : cmp_greater;
            map[h][++l].left = valid_char() == '>' ? cmp_less : cmp_greater;
            ++l;
        }
        if (j != 2)
        rep(i,0,9) map[h+1][i].up = valid_char() == 'v' ? cmp_less : cmp_greater;
        ++h;
    }
    dfs(0, 0);
    return 0;
}


3109: [cqoi2013]新数独

Time Limit: 10 Sec   Memory Limit: 128 MB
Submit: 315   Solved: 208
[ Submit][ Status][ Discuss]

Description

Input

输入一共15行,包含一个新数独的实例。第奇数行包含左右方向的符号(<和>),第偶数行包含上下方向的符号(^和v)。
 

Output

输出包含9行,每行9个1~9的数字,以单个空格隔开。输入保证解惟一。

Sample Input

< > > < > <
v v ^ ^ v v ^ ^ ^
< < > < > <
^ ^ ^ v ^ ^ ^ v v
< < < < > >
> < > > > >
v ^ ^ ^ ^ v v v ^
> > > > < >
v v ^ v ^ v ^ v ^
> < < > > >
< < < < > <
v ^ v v v v ^ ^ v
< > > < < >
^ v v v ^ v ^ v v
< > < > < >

Sample Output

4 9 1 7 3 6 5 2 8
2 3 7 8 1 5 6 4 9
5 6 8 2 4 9 7 3 1
9 1 3 6 5 4 8 7 2
8 5 4 9 7 2 1 6 3
7 2 6 3 8 1 9 5 4
3 4 9 5 6 8 2 1 7
1 8 5 4 2 7 3 9 6
6 7 2 1 9 3 4 8 5

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值