首先,来到这里的人应该都知道数独是什么。
那么,如果没有c++,你,在面对数独时会怎么做?
就是通过某一个格子所在行与列和宫,确定当前格子上的数:
1 | 3 | 4 | ||||||
5(x) | 5(x) | 5(x) | 5 | |||||
5(x) | 5(x) | 5 | ||||||
5 | 5 | |||||||
根据已知三个“5”,排除一宫8个格子,得到“5”的掘除法
#ifndef SHUDUFA_H
#define SHUDUFA_H//定义头文件
#include
using namespace std;
typedef pair P; P ji[11];
int kuai[11][11],lie[11][11],hang[11][11],ma[11][11],k,mm[11][11];
inline int d(int pd,int x,int y) {if(pd==1) return x; else return y;}
inline int find(int num)
{
int jinum=0;
for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) if(ma[i][j]==num) ji[++jinum]=P(i,j);
return jinum;
}//find(i)表示寻找数独上所有i数字的坐标并存于ji[i]中。
inline void biao_hui(int p,int x,int y,int val,int howk)
{
hang[x][val]=p;
lie[y][val]=p;
kuai[howk][val]=p;
mm[x][y]=1;
ma[x][y]=p*val;
k+=2*p-1;
}//biao_hui(p,x,y,val,howk)表示将数独第(x,y)个格子填入val且仅当p=1,标记(p=0时为回溯)
inline void does(int i1,int i2,int j1,int j2,int temp[11][11],int num,int howk)
{
int sum=0,x,y;
for(int i=i1;i<=i2;i++)
{
for(int j=j1;j<=j2;j++)
{
if(temp[i][j]) sum++;
else x=i,y=j;
}
}
if(sum==8&&kuai[howk][num]==0) biao_hui(1,x,y,num,howk);//宫内唯一解
}
inline void tian(int shu,int num)
{
int temp[11][11];
for(int j=1;j<=9;j++) for(int kk=1;kk<=9;kk++) temp[j][kk]=mm[j][kk];//记录那些位置没填,temp与mm此处功能一样。
for(int i=1;i<=shu;i++)
{
int x=ji[i].first,y=ji[i].second;
for(int j=1;j<=9;j++) temp[x][j]=temp[j][y]=1;
}//将数字num用于行列摒除法,再找宫内唯一解。
for(int i=1;i<=3;i++)
{
int xr=i*3,xl=xr-2;
for(int j=1;j<=3;j++) does(xl,xr,(j-1)*3+1,j*3,temp,num,(i-1)*3+j);//找宫内唯一解并填入(上转does)
}
}
inline void does2(int pd)//pd=1为求行内唯一解,pd=2为求列内唯一解
{
if(pd==0)
{
for(int i=1;i<=9;i++) tian(find(i),i);
return;
}
for(int i=1;i<=9;i++)
{
queue q;
int use[11],bu=0;
memset(use,0,sizeof(use));
for(int j=1;j<=9;j++)
{
if(!hang[d(pd,i,j)][d(pd,j,i)])
{
q.push(d(pd,j,i));
use[d(pd,j,i)]=1;
bu++;
}
}
for(int j=1;j<=9;j++)
{
if(ma[d(pd,i,j)][d(pd,j,i)]) continue;
int num=(d(pd,i,j)-1)/3*3+(d(pd,j,i)-1)/3+1;
for(int ki=1;ki<=9;ki++)
{
if(use[ki])
{
int uu=0;
for(int kk=1;kk<=9;kk++)
{
if(use[kk]&&ki!=kk)
{
if(kuai[num][kk]||hang[d(pd,i,j)][kk]||lie[d(pd,j,i)][kk]) uu++;
}
}
if(uu==bu-1&&!kuai[num][ki]&&!hang[d(pd,i,j)][ki]&&!lie[d(pd,j,i)][ki])
{
bu--;
use[ki]=0;
biao_hui(1,d(pd,i,j),d(pd,j,i),ki,num);
}
}
}
}
}
}
#endif
inline void dfs(int nx,int ny)
{
if(ma[nx][ny])
{
if(ny==9)
{
if(nx<9) dfs(nx+1,1);
else return;
}
else dfs(nx,ny+1);
return;
}
for(int i=1;i<=9;i++)
{
if(hang[nx][i]||lie[ny][i]||kuai[((nx-1)/3*3+(ny-1)/3+1)][i]) continue;
biao_hui(1,nx,ny,i,((nx-1)/3*3+(ny-1)/3+1));
if(k==81)
{
print(ma);
continue;
}
if(ny==9)
{
if(nx<9) dfs(nx+1,1);
else continue;
}
else dfs(nx,ny+1);
biao_hui(0,nx,ny,i,((nx-1)/3*3+(ny-1)/3+1));
}
}
#ifndef SHUDUFA_H
#define SHUDUFA_H
#include
using namespace std;
typedef pair P; P ji[11];
int kuai[11][11],lie[11][11],hang[11][11],ma[11][11],k,mm[11][11];
inline int d(int pd,int x,int y) {if(pd==1) return x; else return y;}
inline int find(int num)
{
int jinum=0;
for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) if(ma[i][j]==num) ji[++jinum]=P(i,j);
return jinum;
}
inline void biao_hui(int p,int x,int y,int val,int howk)
{
hang[x][val]=p;
lie[y][val]=p;
kuai[howk][val]=p;
mm[x][y]=1;
ma[x][y]=p*val;
k+=2*p-1;
}
inline void does(int i1,int i2,int j1,int j2,int temp[11][11],int num,int howk)
{
int sum=0,x,y;
for(int i=i1;i<=i2;i++)
{
for(int j=j1;j<=j2;j++)
{
if(temp[i][j]) sum++;
else x=i,y=j;
}
}
if(sum==8&&kuai[howk][num]==0) biao_hui(1,x,y,num,howk);
}
inline void tian(int shu,int num)
{
int temp[11][11];
for(int j=1;j<=9;j++) for(int kk=1;kk<=9;kk++) temp[j][kk]=mm[j][kk];
for(int i=1;i<=shu;i++)
{
int x=ji[i].first,y=ji[i].second;
for(int j=1;j<=9;j++) temp[x][j]=temp[j][y]=1;
}
for(int i=1;i<=3;i++)
{
int xr=i*3,xl=xr-2;
for(int j=1;j<=3;j++) does(xl,xr,(j-1)*3+1,j*3,temp,num,(i-1)*3+j);
}
}
inline void does2(int pd)
{
if(pd==0)
{
for(int i=1;i<=9;i++) tian(find(i),i);
return;
}
for(int i=1;i<=9;i++)
{
queue q;
int use[11],bu=0;
memset(use,0,sizeof(use));
for(int j=1;j<=9;j++)
{
if(!hang[d(pd,i,j)][d(pd,j,i)])
{
q.push(d(pd,j,i));
use[d(pd,j,i)]=1;
bu++;
}
}
for(int j=1;j<=9;j++)
{
if(ma[d(pd,i,j)][d(pd,j,i)]) continue;
int num=(d(pd,i,j)-1)/3*3+(d(pd,j,i)-1)/3+1;
for(int ki=1;ki<=9;ki++)
{
if(use[ki])
{
int uu=0;
for(int kk=1;kk<=9;kk++)
{
if(use[kk]&&ki!=kk)
{
if(kuai[num][kk]||hang[d(pd,i,j)][kk]||lie[d(pd,j,i)][kk]) uu++;
}
}
if(uu==bu-1&&!kuai[num][ki]&&!hang[d(pd,i,j)][ki]&&!lie[d(pd,j,i)][ki])
{
bu--;
use[ki]=0;
biao_hui(1,d(pd,i,j),d(pd,j,i),ki,num);
}
}
}
}
}
}
#endif
#include"bits/stdc++.h"
#include"shudufa.h"
#include"reawri.h"
using namespace std;
inline void dfs(int nx,int ny)
{
if(ma[nx][ny])
{
if(ny==9)
{
if(nx<9) dfs(nx+1,1);
else return;
}
else dfs(nx,ny+1);
return;
}
for(int i=1;i<=9;i++)
{
if(hang[nx][i]||lie[ny][i]||kuai[((nx-1)/3*3+(ny-1)/3+1)][i]) continue;
biao_hui(1,nx,ny,i,((nx-1)/3*3+(ny-1)/3+1));
if(k==81)
{
print(ma);
continue;
}
if(ny==9)
{
if(nx<9) dfs(nx+1,1);
else continue;
}
else dfs(nx,ny+1);
biao_hui(0,nx,ny,i,((nx-1)/3*3+(ny-1)/3+1));
}
}
inline void work()
{
int t=0;string a,b;
while(k<81)
{
if(t==0) a="(区域确定式)",b="(横线确定式)";
if(t==1) a="(横线确定式)",b="(竖线确定式)";
int lastk=k;
for(int i=0;i<=t;i++) does2(t);
if(lastk==k)
{
print(ma);
cout<<("仅有"+a+"法不可行\n加入法"+b+"\n");
t++;
}
if(t>2) break;
}
cout<<"不正常方法:开始搜索......\n";
dfs(1,1);
}
int main()
{
read();
work();
return 0;
}
shudufa.h:
#ifndef SHUDUFA_H
#define SHUDUFA_H
#include
using namespace std;
typedef pair P; P ji[11];
int kuai[11][11],lie[11][11],hang[11][11],ma[11][11],k,mm[11][11];
inline int d(int pd,int x,int y) {if(pd==1) return x; else return y;}
inline int find(int num)
{
int jinum=0;
for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) if(ma[i][j]==num) ji[++jinum]=P(i,j);
return jinum;
}
inline void biao_hui(int p,int x,int y,int val,int howk)
{
hang[x][val]=p;
lie[y][val]=p;
kuai[howk][val]=p;
mm[x][y]=1;
ma[x][y]=p*val;
k+=2*p-1;
}
inline void does(int i1,int i2,int j1,int j2,int temp[11][11],int num,int howk)
{
int sum=0,x,y;
for(int i=i1;i<=i2;i++)
{
for(int j=j1;j<=j2;j++)
{
if(temp[i][j]) sum++;
else x=i,y=j;
}
}
if(sum==8&&kuai[howk][num]==0) biao_hui(1,x,y,num,howk);
}
inline void tian(int shu,int num)
{
int temp[11][11];
for(int j=1;j<=9;j++) for(int kk=1;kk<=9;kk++) temp[j][kk]=mm[j][kk];
for(int i=1;i<=shu;i++)
{
int x=ji[i].first,y=ji[i].second;
for(int j=1;j<=9;j++) temp[x][j]=temp[j][y]=1;
}
for(int i=1;i<=3;i++)
{
int xr=i*3,xl=xr-2;
for(int j=1;j<=3;j++) does(xl,xr,(j-1)*3+1,j*3,temp,num,(i-1)*3+j);
}
}
inline void does2(int pd)
{
if(pd==0)
{
for(int i=1;i<=9;i++) tian(find(i),i);
return;
}
for(int i=1;i<=9;i++)
{
queue q;
int use[11],bu=0;
memset(use,0,sizeof(use));
for(int j=1;j<=9;j++)
{
if(!hang[d(pd,i,j)][d(pd,j,i)])
{
q.push(d(pd,j,i));
use[d(pd,j,i)]=1;
bu++;
}
}
for(int j=1;j<=9;j++)
{
if(ma[d(pd,i,j)][d(pd,j,i)]) continue;
int num=(d(pd,i,j)-1)/3*3+(d(pd,j,i)-1)/3+1;
for(int ki=1;ki<=9;ki++)
{
if(use[ki])
{
int uu=0;
for(int kk=1;kk<=9;kk++)
{
if(use[kk]&&ki!=kk)
{
if(kuai[num][kk]||hang[d(pd,i,j)][kk]||lie[d(pd,j,i)][kk]) uu++;
}
}
if(uu==bu-1&&!kuai[num][ki]&&!hang[d(pd,i,j)][ki]&&!lie[d(pd,j,i)][ki])
{
bu--;
use[ki]=0;
biao_hui(1,d(pd,i,j),d(pd,j,i),ki,num);
}
}
}
}
}
}
#endif
reawri.h:
#ifndef REAWRI_H
#define REAWRI_H
#include"shudufa.h"
#include
using namespace std;
inline void print(int mmm[11][11])
{
for(int i=1;i<=9;i++)
{
for(int j=1;j<=9;j++) cout<>ma[i][j];
if(ma[i][j])
{
int num=(i-1)/3*3+(j-1)/3+1;
biao_hui(1,i,j,ma[i][j],num);
}
}
}
}
#endif