CQOI2013 新数独题解
新数独
下面是一个没有数字,只有大小关系(没错!那些尖角都是“大于”符号!)的数独:
除了大小关系外(注意相邻格子不能相同),还需要满足通常的数独规则:
l 每个格子都是1~9 的数字
l 每行都是1~9的排列
l 每列都是1~9的排列
l 每个3*3的子矩阵(上图中用粗线隔开,一共有3*3个这样的子矩阵)都是1~9的排列
为了美观,每个3*3子矩阵的所有12对相邻格子的大小关系都将给出。
【输入格式】
输入一共15行,包含一个新数独的实例。第奇数行包含左右方向的符号(<和>),第偶数行包含上下方向的符号(^和v)。
【输出格式】
输出包含9行,每行9个1~9的数字,以单个空格隔开。输入保证解惟一。
【输入输出样例】
> < < < > <
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 ^
> > < > < <
5 3 9 4 6 8 2 1 7
2 4 8 1 9 7 3 5 6
1 6 7 2 3 5 9 8 4
6 8 1 7 4 2 5 9 3
3 7 5 9 1 6 8 4 2
9 2 4 5 8 3 7 6 1
7 9 6 8 2 1 4 3 5
4 1 2 3 5 9 6 7 8
8 5 3 6 7 4 1 2 9
考试拿到这个题不敢写啊,没想到直接搜都能得到满分。。。(无力吐槽)
#include<iostream>#include<cstring>#include<algorithm>#include<cstdlib>#include<cstdio>using namespace std;const int INF=0x3f3f3f3f;const int MAXN=110;struct Node{ int v; int Flag; Node *Next;};Node *adj[MAXN*10];Node edge[MAXN*MAXN];Node *Cnt1=&edge[0];void addedge(int u,int v,int Flag){ Node *p=++Cnt1; p->v=v; p->Flag=Flag;p->Next=adj[u]; adj[u]=p;}int High[MAXN*10],Low[MAXN*10];inline int Get_Pos(int x,int y){ return (x-1)*9+y;}int Ans[MAXN*MAXN],visc[MAXN],visr[MAXN],visk[MAXN];inline int Get_c(int x,int y){ return y;}inline int Get_r(int x,int y){ return x;}inline int Get_k(int x,int y){ return (x%3==0?x/3-1:x/3)*3+(y%3==0?y/3:y/3+1);}void DFS(int x,int y){ if(x>9){ for(int i=1;i<=9;++i){ for(int j=1;j<=8;++j) printf("%d ",Ans[Get_Pos(i,j)]); printf("%d\n",Ans[Get_Pos(i,9)]); } exit(0); } if(y>9){ DFS(x+1,1); return ; } int Pos=Get_Pos(x,y); int MaxSize=9,MinSize=1; for(Node *p=adj[Get_Pos(x,y)];p;p=p->Next){ int v=p->v,Flag=p->Flag; if(Ans[v]!=INF){ if(Flag==1){ MinSize=max(MinSize,Ans[v]+1); } else{ MaxSize=min(MaxSize,Ans[v]-1); } } } for(int a=max(MinSize,Low[Pos]);a<=min(MaxSize,High[Pos]);++a){ int c,r,k; c=Get_c(x,y); r=Get_r(x,y); k=Get_k(x,y); if((!(1<<a&visc[c]))&&(!(1<<a&visr[r]))&&(!(1<<a&visk[k]))) { visc[c]^=(1<<a); visr[r]^=(1<<a); visk[k]^=(1<<a); Ans[Get_Pos(x,y)]=a; DFS(x,y+1); visc[c]^=(1<<a); visr[r]^=(1<<a); visk[k]^=(1<<a); Ans[Get_Pos(x,y)]=INF; } }}int main(){ //freopen("sudoku4.in","r",stdin); for(int i=0;i<MAXN*10;++i){ High[i]=9; Low[i]=1; } memset(Ans,0x3f,sizeof(Ans)); for(int i=0;i<3;++i){ //分块 char ch; for(int j=0;j<3;++j) for(int k=1;k<=2;++k){ do{ch=getchar();}while(ch!='>'&&ch!='<'); if(ch=='>'){ Low[i*27+j*3+k]++; High[i*27+j*3+k+1]--; addedge(i*27+j*3+k,i*27+j*3+k+1,1); addedge(i*27+j*3+k+1,i*27+j*3+k,0); } if(ch=='<'){ High[i*27+j*3+k]--; Low[i*27+j*3+k+1]++; addedge(i*27+j*3+k,i*27+j*3+k+1,0); addedge(i*27+j*3+k+1,i*27+j*3+k,1); } } for(int j=1;j<=9;++j){ do{ch=getchar();}while(ch!='v'&&ch!='^'); if(ch=='v'){ Low[i*27+j]++; High[i*27+j+9]--; addedge(i*27+j,i*27+j+9,1); addedge(i*27+j+9,i*27+j,0); } if(ch=='^'){ High[i*27+j]--; Low[i*27+j+9]++; addedge(i*27+j,i*27+j+9,0); addedge(i*27+j+9,i*27+j,1); } } for(int j=0;j<3;++j) for(int k=1;k<=2;++k){ do{ch=getchar();}while(ch!='<'&&ch!='>'); if(ch=='>'){ Low[i*27+9+j*3+k]++; High[i*27+9+j*3+k+1]--; addedge(i*27+9+j*3+k,i*27+9+j*3+k+1,1); addedge(i*27+9+j*3+k+1,i*27+9+j*3+k,0); } if(ch=='<'){ High[i*27+9+j*3+k]--; Low[i*27+9+j*3+k+1]++; addedge(i*27+9+j*3+k,i*27+9+j*3+k+1,0); addedge(i*27+9+j*3+k+1,i*27+9+j*3+k,1); } } for(int j=1;j<=9;++j){ do{ch=getchar();}while(ch!='v'&&ch!='^'); if(ch=='v'){ Low[i*27+9+j]++; High[i*27+18+j]--; addedge(i*27+9+j,i*27+18+j,1); addedge(i*27+18+j,i*27+9+j,0); } if(ch=='^'){ High[i*27+9+j]--; Low[i*27+18+j]++; addedge(i*27+9+j,i*27+18+j,0); addedge(i*27+18+j,i*27+9+j,1); } } for(int j=0;j<3;++j) for(int k=1;k<=2;++k){ do{ch=getchar();}while(ch!='<'&&ch!='>'); if(ch=='>'){ Low[i*27+18+k+j*3]++; High[i*27+18+k+1+j*3]--; addedge(i*27+18+k+j*3,i*27+18+k+1+j*3,1); addedge(i*27+18+k+j*3+1,i*27+18+k+j*3,0); } if(ch=='<'){ High[i*27+18+k+j*3]--; Low[i*27+18+k+1+j*3]++; addedge(i*27+18+k+j*3,i*27+18+k+1+j*3,0); addedge(i*27+18+k+j*3+1,i*27+18+k+j*3,1); } } } /*for(int i=1;i<=9;++i){ for(int j=1;j<=9;++j) printf("%d ",High[Get_Pos(i,j)]); printf("\n"); } printf("\n"); for(int i=1;i<=9;++i){ for(int j=1;j<=9;++j) printf("%d ",Low[Get_Pos(i,j)]); printf("\n"); } printf("\n");*/ DFS(1,1); return 0;}

浙公网安备 33010602011771号