2 条题解
-
0
超时60分代码
#include <bits/stdc++.h> using namespace std; int a[10][10], b[10][10]; bool vrow[10][10], vcol[10][10], vb[10][10], bk; void dfs(int x, int y) { if (bk) return; if (x == 10) { bk = 1; return; } if (y == 10) { dfs(x + 1, 1); return; } if (a[x][y] != 0) dfs(x, y + 1); else { for (int t = 1; t <= 9; t++) { if (!vrow[x][t] && !vcol[y][t] && !vb[b[x][y]][t]) { vrow[x][t] = vcol[y][t] = vb[b[x][y]][t] = 1; a[x][y] = t; dfs(x, y + 1); if (bk) return; vrow[x][t] = vcol[y][t] = vb[b[x][y]][t] = 0; a[x][y] = 0; } } } } int main() { for (int i = 1; i <= 9; i++) for (int j = 1; j <= 9; j++) b[i][j] = (i - 1) / 3 * 3 + (j + 2) / 3; char s[90]; while (scanf("%s", s) != EOF) { memset(vrow, 0, sizeof(vrow)); memset(vcol, 0, sizeof(vcol)); memset(vb, 0, sizeof(vb)); for (int i = 1; i <= 9; i++) for (int j = 1; j <= 9; j++) { a[i][j] = s[(i - 1) * 9 + j - 1] - 48; if (a[i][j] != 0) { vrow[i][a[i][j]] = 1; vcol[j][a[i][j]] = 1; vb[b[i][j]][a[i][j]] = 1; } } bk = 0; dfs(1, 1); for (int i = 1; i <= 9; i++) for (int j = 1; j <= 9; j++) printf("%d", a[i][j]); printf("\n"); } return 0; }超时80分代码
#include <bits/stdc++.h> using namespace std; int a[10][10], b[10][10]; int vrow[10], vcol[10], vb[10]; bool bk; map<int, int> Map; void dfs(int x, int y) { if (bk) return; if (x == 10) { bk = 1; return; } if (y == 10) { dfs(x + 1, 1); return; } if (a[x][y] != 0) dfs(x, y + 1); else { for (int v = vrow[x] & vcol[y] & vb[b[x][y]]; v; v -= v & -v) { int t = Map[v & -v]; a[x][y] = t; vrow[x] ^= 1 << (t - 1); vcol[y] ^= 1 << (t - 1); vb[b[x][y]] ^= 1 << (t - 1); dfs(x, y + 1); if (bk == 1) return; a[x][y] = 0; vrow[x] ^= 1 << (t - 1); vcol[y] ^= 1 << (t - 1); vb[b[x][y]] ^= 1 << (t - 1); } } } int main() { for (int i = 1; i <= 9; i++) for (int j = 1; j <= 9; j++) b[i][j] = (i - 1) / 3 * 3 + (j + 2) / 3; for (int i = 1; i <= 9; i++) Map[1 << (i - 1)] = i; char s[90]; while (scanf("%s", s) != EOF) { for (int i = 1; i <= 9; i++) vrow[i] = vcol[i] = vb[i] = (1 << 9) - 1; for (int i = 1; i <= 9; i++) for (int j = 1; j <= 9; j++) { a[i][j] = s[(i - 1) * 9 + j - 1] - 48; if (a[i][j] != 0) { vrow[i] ^= 1 << (a[i][j] - 1); vcol[j] ^= 1 << (a[i][j] - 1); vb[b[i][j]] ^= 1 << (a[i][j] - 1); } } bk = 0; dfs(1, 1); for (int i = 1; i <= 9; i++) for (int j = 1; j <= 9; j++) printf("%d", a[i][j]); printf("\n"); } return 0; }位运算(优化版)
#include <bits/stdc++.h> using namespace std; int a[10][10], b[10][10], vrow[10], vcol[10], vb[10], ones[513], Map[513]; bool bk; void dfs(int tot) { if (bk) return; if (tot == 0) { bk = true; return; } int tmp = 10, x, y; for (int i = 1; i <= 9; i++) for (int j = 1; j <= 9; j++) if (a[i][j] == 0) { int v = vrow[i] & vcol[j] & vb[b[i][j]]; if (v == 0) return; if (ones[v] < tmp) { tmp = ones[v]; x = i, y = j; } } for (int v = vrow[x] & vcol[y] & vb[b[x][y]]; v; v -= v & -v) { int t = Map[v & -v]; a[x][y] = t; vrow[x] ^= 1 << (t - 1); vcol[y] ^= 1 << (t - 1); vb[b[x][y]] ^= 1 << (t - 1); dfs(tot - 1); if (bk) return; a[x][y] = 0; vrow[x] ^= 1 << (t - 1); vcol[y] ^= 1 << (t - 1); vb[b[x][y]] ^= 1 << (t - 1); } } int main() { for (int i = 1; i <= 9; i++) for (int j = 1; j <= 9; j++) b[i][j] = (i - 1) / 3 * 3 + (j + 2) / 3; memset(ones, 0, sizeof(ones)); for (int i = 0; i < (1 << 9); i++) for (int j = i; j; j -= j & -j) ones[i]++; for (int i = 1; i <= 9; i++) Map[1 << (i - 1)] = i; char s[100]; while (scanf("%s", s) != EOF) { for (int i = 1; i <= 9; i++) vrow[i] = vcol[i] = vb[i] = (1 << 9) - 1; int tot = 0; for (int i = 1; i <= 9; i++) for (int j = 1; j <= 9; j++) { a[i][j] = s[(i - 1) * 9 + j - 1] - '0'; if (a[i][j] != 0) { vrow[i] ^= 1 << (a[i][j] - 1); vcol[j] ^= 1 << (a[i][j] - 1); vb[b[i][j]] ^= 1 << (a[i][j] - 1); } else tot++; } bk = false; dfs(tot); for (int i = 1; i <= 9; i++) for (int j = 1; j <= 9; j++) printf("%d", a[i][j]); printf("\n"); } return 0; } -
0
超时60分代码:
#include<bits/stdc++.h> using namespace std; int a[10][10],b[10][10]; bool vrow[10][10],vcol[10][10],vb[10][10],bk; void dfs(int x,int y) { if(bk) return ; if(x==10) { bk=1; return ; } if(y==10) { dfs(x+1,1); return ; } if(a[x][y]!=0) dfs(x,y+1); else { for(int t=1;t<=9;t++) { if( vrow[x][t]==0 && vcol[y][t]==0 && vb[ b[x][y] ][t]==0) { vrow[x][t]=vcol[y][t]=vb[ b[x][y] ][t]=1; a[x][y]=t; dfs(x,y+1);if(bk) return; vrow[x][t]=vcol[y][t]=vb[ b[x][y] ][t]=0; a[x][y]=0; } } } } int main() { for(int i=1;i<=9;i++)for(int j=1;j<=9;j++)b[i][j]=(i-1)/3 * 3+ (j+2)/3; char s[90]; while(scanf("%s",s)!=EOF) { memset(vrow,0,sizeof(vrow));memset(vcol,0,sizeof(vcol));memset(vb,0,sizeof(vb)); for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) { a[i][j]=s[(i-1)*9+j-1]-48; if(a[i][j]!=0) { vrow[i][a[i][j]]=1; vcol[j][a[i][j]]=1; vb[b[i][j]][a[i][j]]=1; } } bk=0; dfs(1,1); for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) printf("%d",a[i][j]); printf("\n"); } return 0; }
超时80分代码:#include<bits/stdc++.h> using namespace std; int a[10][10],b[10][10]; int vrow[10],vcol[10],vb[10]; bool bk; map<int,int>Map; void dfs(int x,int y) { if(bk) return ; if(x==10) { bk=1; return ; } if(y==10) { dfs(x+1,1); return ; }if(a[x][y]!=0) dfs(x,y+1); else { for(int v=vrow[x] & vcol[y] & vb[b[x][y]]; v; v-=v&-v)//v & -v为lowbit(v) { int t=Map[(v&-v)]; //最小的选择 a[x][y]=t; vrow[x] ^= 1 << (t-1); vcol[y] ^= 1 << (t-1); vb[b[x][y]] ^= 1 << (t-1); dfs(x,y+1);if(bk==1) return ; //成功 a[x][y]=0; vrow[x] ^= 1 << (t-1); vcol[y] ^= 1 << (t-1); vb[b[x][y]] ^= 1 << (t-1); } }} int main() { for(int i=1;i<=9;i++)for(int j=1;j<=9;j++)b[i][j]=(i-1)/3 * 3+ (j+2)/3; for (int i=1;i<=9; i++)Map[1 << (i-1)] = i; char s[90]; while(scanf("%s",s)!=EOF) { for(int i=1;i<=9;i++)vrow[i]=vcol[i]=vb[i]=(1<<9)-1; for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) { a[i][j]=s[(i-1)*9+j-1]-48; if(a[i][j]!=0) { vrow[i] ^= 1 << (a[i][j]-1); vcol[j] ^= 1 << (a[i][j]-1); vb[b[i][j]] ^= 1 << (a[i][j]-1); } } bk=0; dfs(1,1); for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) printf("%d",a[i][j]); printf("\n"); } return 0; }
位运算:</p>#include<bits/stdc++.h>//scy的教学代码 using namespace std; int a[10][10],b[10][10], vrow[10], vcol[10], vb[10] , ones[513], Map[513]; //a就是最后的答案 //vrow[i]表示第i行 能填所有的数字的状态 //vcol[j]表示第j列 能填所有的数字的状态 //vb[k] 表示第k个3*3的矩阵 能填所有的数字的状态 //ones[v]表示状态v的二进制有多少个1 //Map[x]:x只能是2^(k-1)(1<=k<=9),Map[x]表示k。 //Map[1]=1,Map[10]=2,Map[100]=3……Map[1 0000 0000]=9 bool bk; void dfs(int tot) { if(bk==1) return ; if(tot==0) {bk=True;return ;} int tmp=10, x, y; for(int i=1;i<=9;i++) for(int j=1; j<=9;j++)if(a[i][j]==0) { int v=vrow[i] & vcol[j] & vb[b[i][j]];//此时的v为格子(i,j)能填所有数字的状态 if(v==0) return ; if(ones[v] < tmp)//找到格子(x,y):为目前能填最少数字的格子 { tmp = ones[v]; x = i, y = j; } } for(int v=vrow[x] & vcol[y] & vb[b[x][y]]; v; v-=v&-v)//v & -v为lowbit(v) { int t=Map[(v&-v)]; //最小的选择 a[x][y]=t; vrow[x] ^= 1 << (t-1); vcol[y] ^= 1 << (t-1); vb[b[x][y]] ^= 1 << (t-1); dfs(tot-1);if(bk==1) return ; //成功 a[x][y]=0; vrow[x] ^= 1 << (t-1); vcol[y] ^= 1 << (t-1); vb[b[x][y]] ^= 1 << (t-1); } } int main() { ////格子(x,y)所在的3*3的矩阵的编号,编号为1~9 for(int i=1;i<=9;i++)for(int j=1;j<=9;j++)b[i][j]=(i-1)/3 * 3+ (j+2)/3; memset(ones,0,sizeof(ones)); for(int i=0;i< 1<<9; i++) for(int j=i;j;j -= j&-j) ones[i]++; for (int i=1;i<=9; i++)Map[1 << (i-1)] = i; char s[100]; while (scanf("%s", s)!=EOF) { for(int i=1;i<=9;i++)for(int j=1;j<=9;j++)a[i][j]=s[(i-1)* 9+j -1]-'0';//转换 for(int i=1;i<=9;i++)vrow[i]=vcol[i]=vb[i]=(1<<9)-1; int tot=0;//tot统计有多少个a[i][j]==0 for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) if(a[i][j]!=0) { vrow[i] ^= 1 << (a[i][j]-1); vcol[j] ^= 1 << (a[i][j]-1); vb[b[i][j]] ^= 1 << (a[i][j]-1); } else tot++; bk=False;dfs(tot); for(int i=1;i<=9;i++)for(int j=1;j<=9;j++) printf("%d",a[i][j]); printf("\n"); } return 0; }
用堆优化反而超时,要10秒,不知为什么,这里也贴下堆优化超时的代码:#include<bits/stdc++.h>//scy的教学代码 using namespace std; int a[10][10],b[10][10], vrow[10], vcol[10], vb[10] , ones[513], Map[513]; //a就是最后的答案 //vrow[i]表示第i行 能填所有的数字的状态 //vcol[j]表示第j列 能填所有的数字的状态 //vb[k] 表示第k个3*3的矩阵 能填所有的数字的状态 //ones[v]表示状态v的二进制有多少个1 //Map[x]:x只能是2^(k-1)(1<=k<=9),Map[x]表示k。 //Map[1]=1,Map[10]=2,Map[100]=3……Map[1 0000 0000]=9 struct node{ int k,x,y; bool operator < (const node &a) const {return k>a.k;} }; priority_queue<node> q; bool bk; void dfs(int tot) { if(bk==1) return ; if(tot==0) { bk=True; return ; }</p>int k = q.top().k ,x = q.top().x, y = q.top().y;q.pop(); for(int v=vrow[x] & vcol[y] & vb[b[x][y]]; v; v-=v&-v)//v & -v为lowbit(v) { int t=Map[(v&-v)]; //最小的选择 a[x][y]=t; vrow[x] ^= 1 << (t-1); vcol[y] ^= 1 << (t-1); vb[b[x][y]] ^= 1 << (t-1); dfs(tot-1);if(bk==1) return ; //成功 a[x][y]=0; vrow[x] ^= 1 << (t-1); vcol[y] ^= 1 << (t-1); vb[b[x][y]] ^= 1 << (t-1); } q.push({k,x,y});} int main() { ////格子(x,y)所在的3*3的矩阵的编号,编号为1~9 for(int i=1;i<=9;i++)for(int j=1;j<=9;j++)b[i][j]=(i-1)/3 * 3+ (j+2)/3; memset(ones,0,sizeof(ones)); for(int i=0;i< 1<<9; i++) for(int j=i;j;j -= j&-j) ones[i]++; for (int i=1;i<=9; i++)Map[1 << (i-1)] = i;
char s[100]; while (scanf("%s", s)!=EOF) { while(!q.empty())q.pop(); for(int i=1;i<=9;i++)for(int j=1;j<=9;j++)a[i][j]=s[(i-1)* 9+j -1]-'0';//转换 for(int i=1;i<=9;i++)vrow[i]=vcol[i]=vb[i]=(1<<9)-1; int tot=0;//tot统计有多少个a[i][j]==0 for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) if(a[i][j]!=0) { vrow[i] ^= 1 << (a[i][j]-1); vcol[j] ^= 1 << (a[i][j]-1); vb[b[i][j]] ^= 1 << (a[i][j]-1); } else tot++; for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) if(a[i][j]==0) { int v=vrow[i] &vcol[j] &vb[b[i][j]]; q.push({ones[v],i,j}); } bk=False;dfs(tot); for(int i=1;i<=9;i++)for(int j=1;j<=9;j++) printf("%d",a[i][j]); printf("\n"); } return 0;}
- 1
信息
- ID
- 1081
- 时间
- 1500ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- 递交数
- 339
- 已通过
- 46
- 上传者