[cqoi2013]新数独

[cqoi2013]新数独

题目

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

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

解题报告

裸搜

记录一下各点之间的大小关系,记录一下各点的出度入度来确定枚举范围(这里的出度入度指有几个数比他大,几个数比他小)

搜就可以了

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<cstdlib>
  5 using namespace std;
  6 inline char read(){
  7     char ch(getchar());
  8     while(ch!=‘<‘&&ch!=‘>‘&&ch!=‘v‘&&ch!=‘^‘)
  9         ch=getchar();
 10     return ch;
 11 }
 12 bool h[10][10],l[10][10],jgg[10][10];
 13 int dx[10][10][10][10];
 14 int indegree[10][10],outdegree[10][10];
 15 inline void insert(int a,int b,int c,int d){
 16     ++indegree[c][d];
 17     ++outdegree[a][b];
 18     dx[a][b][c][d]=1;
 19     dx[c][d][a][b]=-1;
 20 }
 21 int ans[10][10];
 22 bool vis[10][10];
 23 inline bool judge(int x,int y,int zhi){
 24     if(x!=1&&vis[x-1][y]&&dx[x][y][x-1][y]!=0){
 25         if(dx[x][y][x-1][y]==1&&zhi>=ans[x-1][y])
 26             return false;
 27         if(dx[x][y][x-1][y]==-1&&zhi<=ans[x-1][y])
 28             return false;
 29     }
 30     if(x!=9&&vis[x+1][y]&&dx[x][y][x+1][y]!=0){
 31         if(dx[x][y][x+1][y]==1&&zhi>=ans[x+1][y])
 32             return false;
 33         if(dx[x][y][x+1][y]==-1&&zhi<=ans[x+1][y])
 34             return false;
 35     }
 36     if(y!=1&&vis[x][y-1]&&dx[x][y][x][y-1]!=0){
 37         if(dx[x][y][x][y-1]==1&&zhi>=ans[x][y-1])
 38             return false;
 39         if(dx[x][y][x][y-1]==-1&&zhi<=ans[x][y-1])
 40             return false;
 41     }
 42     if(y!=9&&vis[x][y+1]&&dx[x][y][x][y+1]!=0){
 43         if(dx[x][y][x][y+1]==1&&zhi>=ans[x][y+1])
 44             return false;
 45         if(dx[x][y][x][y+1]==-1&&zhi<=ans[x][y+1])
 46             return false;
 47     }
 48     return true;
 49 }
 50 inline void print(){
 51     for(int i=1;i<=9;++i){
 52         for(int j=1;j<9;++j)
 53             printf("%d ",ans[i][j]);
 54         printf("%d\n",ans[i][9]);
 55     }
 56 }
 57 int bl[10][10];
 58 inline void dfs(int x,int y){
 59     vis[x][y]=1;
 60     for(int i=indegree[x][y]+1;i<=9-outdegree[x][y];++i)
 61         if(!h[x][i]&&!l[y][i]&&!jgg[bl[x][y]][i]&&judge(x,y,i)){
 62             h[x][i]=l[y][i]=jgg[bl[x][y]][i]=1;
 63             ans[x][y]=i;
 64             if(x==9&&y==9){
 65                 print();
 66                 exit(0);
 67             }
 68             if(y==9)
 69                 dfs(x+1,1);
 70             else
 71                 dfs(x,y+1);
 72             h[x][i]=l[y][i]=jgg[bl[x][y]][i]=0;
 73         }
 74     vis[x][y]=0;
 75 }
 76 int main(){
 77     for(int i=1,cnt=0;i<=9;++i)
 78         for(int j=1;j<=9;++j)
 79             bl[i][j]=((i-1)/3)*3+(j-1)/3+1;
 80     for(int i=1;i<=15;++i){
 81         int pos1,pos2;
 82         if(i==1||i==3||i==5||i==6||i==8||i==10||i==11||i==13||i==15){
 83             if(i==1)pos1=1;
 84             if(i==3)pos1=2;
 85             if(i==5)pos1=3;
 86             if(i==6)pos1=4;
 87             if(i==8)pos1=5;
 88             if(i==10)pos1=6;
 89             if(i==11)pos1=7;
 90             if(i==13)pos1=8;
 91             if(i==15)pos1=9;
 92             for(int j=1;j<=6;++j){
 93                 if(j==1)pos2=1;
 94                 if(j==2)pos2=2;
 95                 if(j==3)pos2=4;
 96                 if(j==4)pos2=5;
 97                 if(j==5)pos2=7;
 98                 if(j==6)pos2=8;
 99                 char tp(read());
100                 if(tp==‘<‘)
101                     insert(pos1,pos2,pos1,pos2+1);
102                 else
103                     insert(pos1,pos2+1,pos1,pos2);
104             }
105         }
106         else{
107             if(i==2)pos1=1;
108             if(i==4)pos1=2;
109             if(i==7)pos1=4;
110             if(i==9)pos1=5;
111             if(i==12)pos1=7;
112             if(i==14)pos1=8;
113             for(int j=1;j<=9;++j){
114                 pos2=j;
115                 char tp(read());
116                 if(tp==‘^‘)
117                     insert(pos1,pos2,pos1+1,pos2);
118                 else
119                     insert(pos1+1,pos2,pos1,pos2);
120             }
121         }
122     }
123     dfs(1,1);
124 }

时间: 2024-10-29 19:07:41

[cqoi2013]新数独的相关文章

bzoj3109 [cqoi2013]新数独

Description Input 输入一共15行,包含一个新数独的实例.第奇数行包含左右方向的符号(<和>),第偶数行包含上下方向的符号(^和v). Output 输出包含9行,每行9个1~9的数字,以单个空格隔开.输入保证解惟一. Sample Input < > > < > < v v ^ ^ v v ^ ^ ^< < > < > < ^ ^ ^ v ^ ^ ^ v v< < < < >

bzoj 3109: [cqoi2013]新数独

1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 int ha[10][10],li[10][10],xi[10][10],a[10][10],bh[10][10],bl[10][10],kg; 5 char ch[5]; 6 bool pan(int x,int y,int i) 7 { 8 if(ha[x][i]||li[y][i]||xi[(x-1)/3*3+(y-1)/3][i]) 9 retu

【搜索】bzoj3109 [cqoi2013]新数独

搜索,没什么好说的.要注意读入. Code: #include<cstdio> #include<cstdlib> using namespace std; const int num[10][10]= {{0,0,0,0,0,0,0,0,0,0}, {0,1,1,1,2,2,2,3,3,3}, {0,1,1,1,2,2,2,3,3,3}, {0,1,1,1,2,2,2,3,3,3}, {0,4,4,4,5,5,5,6,6,6}, {0,4,4,4,5,5,5,6,6,6}, {0

bzoj3109【CQOI2013】新数独

3109: [cqoi2013]新数独 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 365  Solved: 229 [Submit][Status][Discuss] Description Input 输入一共15行,包括一个新数独的实例. 第奇数行包括左右方向的符号(<和>),第偶数行包括上下方向的符号(^和v). Output 输出包括9行,每行9个1~9的数字,以单个空格隔开. 输入保证解惟一. Sample Input <

BZOJ 3105: [cqoi2013]新Nim游戏

3105: [cqoi2013]新Nim游戏 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1064  Solved: 624[Submit][Status][Discuss] Description 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴.可以只拿一根,也可以拿走整堆火柴,但不能同时从超过一堆火柴中拿.拿走最后一根火柴的游戏者胜利. 本题的游

3105: [cqoi2013]新Nim游戏 异或高消 &amp;&amp; 拟阵

3105: [cqoi2013]新Nim游戏 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 535  Solved: 317[Submit][Status][Discuss] Description 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴.可以只拿一根,也可以拿走整堆火柴,但不能同时从超过一堆火柴中拿.拿走最后一根火柴的游戏者胜利. 本题的游戏

BZOJ3105: [cqoi2013]新Nim游戏

题解: 线性基?类似于向量上的基底. 此题题解戳这里:http://blog.csdn.net/wyfcyx_forever/article/details/39477673 代码: 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #include<iostream> 7 #incl

BZOJ3105: [cqoi2013]新Nim游戏 博弈论+线性基

一个原来写的题. 既然最后是nim游戏,且玩家是先手,则希望第二回合结束后是一个异或和不为0的局面,这样才能必胜. 所以思考一下我们要在第一回合留下线性基 然后就是求线性基,因为要取走的最少,所以排一下序,从大到小求. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 #include<cmath> 6 #include<algor

【BZOJ3105】[cqoi2013]新Nim游戏 贪心+线性基

[BZOJ3105][cqoi2013]新Nim游戏 Description 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴.可以只拿一根,也可以拿走整堆火柴,但不能同时从超过一堆火柴中拿.拿走最后一根火柴的游戏者胜利. 本题的游戏稍微有些不同:在第一个回合中,第一个游戏者可以直接拿走若干个整堆的火柴.可以一堆都不拿,但不可以全部拿走.第二回合也一样,第二个游戏者也有这样一次机会.从第三个回合(又轮到