1. 程式人生 > >CQOI2013 新數獨

CQOI2013 新數獨

org 開始 cin tar clas tps math putchar 斷點

傳送門

這道題也是很暴力的搜索啊……

因為數獨一開始全是空的,只有許許多多的大小限制條件,那也沒必要糾結從哪開始搜索了,直接暴力搜索之後判斷一下是否合法。

這題最惡心的是讀入。現學了一招判斷點在哪個塊內,用lim[g][i][j],表示在g宮內i和j這兩個格子的大小關系,處理還是相當復雜的(代碼裏有),之後就沒什麽要註意的,全是爆搜。

最後這個爆搜還會T兩個點,要開O2.我也想不到有什麽更好的優化了……

看一下代碼。

// luogu-judger-enable-o2
#include<cstdio>
#include<algorithm>
#include<cstring>
#include
<iostream> #include<cmath> #include<ctime> #define rep(i,a,n) for(int i = a;i <= n;i++) #define per(i,n,a) for(int i = n;i >= a;i--) #define enter putchar(‘\n‘) using namespace std; typedef long long ll; const int M = 1005; const int mod = 1e9 + 7; int read() { int ans = 0,op = 1
; char ch = getchar(); while(ch < 0 || ch > 9) { if(ch == -) op = -1; ch = getchar(); } while(ch >= 0 && ch <= 9) { ans *= 10; ans += ch - 0; ch = getchar(); } return ans * op; } int num[11][11],hcnt,lcnt,px,py; int lim[11
][11][11],vish[11][11],visl[11][11],visg[11][11]; char s; void print() { rep(i,1,9) { rep(j,1,9) printf("%d ",num[i][j]);enter; } } bool pd(int g,int pos,int k) { rep(j,1,9) { int dx = g / 3 * 3 + (j - 1) / 3 + 1,dy = g % 3 * 3 + (j - 1) % 3 + 1; if(lim[g][pos][j] == 1 && num[dx][dy] && k < num[dx][dy]) return 0; if(lim[g][pos][j] == 2 && num[dx][dy] && k > num[dx][dy]) return 0; } return 1; } void buildh(int i,int k) { rep(j,1,6) { int g = (i - 1) * 3 + ((j - 1) >> 1); int pos = ((k - 1) >> 1) * 3 + ((j - 1) & 1) + 1; cin >> s; lim[g][pos][pos+1] = (s == >) ? 1 : 2; lim[g][pos+1][pos] = (s == >) ? 2 : 1; } } void buildl(int i,int k) { rep(j,1,9) { int g = (i - 1) * 3 + (j - 1) / 3; int pos = ((k-1) >> 1) * 3 + (j - 1) % 3 + 1; cin >> s; lim[g][pos][pos+3] = (s == v) ? 1 : 2; lim[g][pos+3][pos] = (s == v) ? 2 : 1; } } void build() { rep(i,1,3) rep(k,1,5) (k & 1) ? buildh(i,k) : buildl(i,k); } void dfs(int x,int y) { int g = ((x - 1) / 3) * 3 + (y - 1) / 3; int pos = (x - 1) % 3 * 3 + (y - 1) % 3 + 1; rep(k,1,9) { if(vish[x][k] || visl[y][k] || visg[g][k]) continue; if(!pd(g,pos,k)) continue; vish[x][k] = visl[y][k] = visg[g][k] = 1,num[x][y] = k; //print(); if(x == 9 && y == 9) print(),exit(0); else (y == 9) ? dfs(x+1,1) : dfs(x,y+1); vish[x][k] = visl[y][k] = visg[g][k] = 0,num[x][y] = 0; } } int main() { build(); /*rep(i,1,9) { rep(j,1,9) { printf("%d ",lim[1][i][j]); } enter; }*/ dfs(1,1); return 0; }

CQOI2013 新數獨