数独-DFS

T1
T2
T3
这三题,貌似很像呀,算是多倍经验了吧QAQ
好吧,其实完全不一样QAQ
先看T1,这是裸的数独了呀QAQ,直接暴力上呀

#include<bits/stdc++.h>
using namespace std;
int i,j,k,n,Len=0,ans[11][11];
int Num[50];
bool boo_x[10][10],boo_y[10][10],boo_QAQ[10][10];//三个bool型数组判断当前行,列,3*3矩阵中这个数字有没有出现过
int check(int x,int y)
{return (y-1)/3+1+((x-1)/3)*3;}//这个很重要呀,计算出这个点在哪个3*3的矩阵中位置
void DFS(int x,int y)//DFS,其实就是暴力了QAQ
{
  if(x==10)//如果搜出了,就是前面的都符合了,就输出QAQ
  {
  	int i,j;
  	for(i=1;i<=9;i++)
  	{
  	  for(j=1;j<=9;j++)
  	  cout<<ans[i][j]<<" ";
  	  cout<<endl;
	}
	exit(0);//直接退出
  }
  int i;
  if(!ans[x][y])//如果当前这个位置开始没有数字则放一个数字进去
  {
    for(i=1;i<=9;i++)
    if(boo_x[x][i]&&boo_y[y][i]&&boo_QAQ[check(x,y)][i])
    {
  	  boo_x[x][i]=0;
  	  boo_y[y][i]=0;
  	  boo_QAQ[check(x,y)][i]=0;//当前行,列,3*3矩阵中的这个数不能再放
  	  ans[x][y]=i;
  	  if(y!=9)
  	  DFS(x,y+1);else DFS(x+1,1);
  	  boo_x[x][i]=1;
  	  boo_y[y][i]=1;
  	  boo_QAQ[check(x,y)][i]=1;//当前行,列,3*3矩阵中又可以放这个数了,QAQ
  	  ans[x][y]=0;
    }
  }
  else
  {if(y!=9)DFS(x,y+1);else DFS(x+1,1);}//这个位置有数了,就直接向下搜
}
int main()
{
  for(i=1;i<=9;i++)
  for(j=1;j<=9;j++)
  boo_x[i][j]=1,boo_y[i][j]=1,boo_QAQ[i][j]=1;
  for(i=1;i<=9;i++)
  for(j=1;j<=9;j++)
  {
    cin>>ans[i][j];
    boo_x[i][ans[i][j]]=0;
    boo_y[j][ans[i][j]]=0;
    boo_QAQ[check(i,j)][ans[i][j]]=0;
    //读入的数自然在这个3*3矩阵,行,列不能放了QAQ
  }
  DFS(1,1);//搜索
} 

先过了这题QAQ,感觉数独貌似很水 个蛇呀
T2:
这个是个蛇?
直接上暴力,TLE(亲测开O2 80分)
优化QAQing…
先排0的个数少的搜的就少了

这个是一个结构体QAQ:

struct QAQ
{
  int sum/*存放这行有几个0*/,num/*存放这个是第几行*/;
}QwQ[11];

这个是一个cmp

bool cmp(QAQ a,QAQ b)
{
  return a.sum<b.sum;
}

接下来就是这么一段了:

  ...//事先要吧sum和num里的值放好
  sort(QwQ+1,QwQ+10,cmp);//排序
  for(i=1;i<=10;i++)
  Next[QwQ[i].num]=QwQ[i+1].num;
  Next[QwQ[9].num]=10;
  Next[0]=QwQ[1].num;
  DFS(Next[0],1);//从最小的开始搜

排个序再搜
代码差不多了

#include<bits/stdc++.h>
using namespace std;
int i,j,k,n,Len=0,ans[11][11],Ans=0;
int Num[50];
bool boo_x[10][10],boo_y[10][10],boo_QAQ[10][10];
int Next[11];
int check(int x,int y)
{return (y-1)/3+1+((x-1)/3)*3;}
struct QAQ
{
  int sum,num;
}QwQ[11];
bool cmp(QAQ a,QAQ b)
{
  return a.sum<b.sum;
}
void DFS(int x,int y)
{
  if(x==10)
  {
  	int i,j,sum=0;
  	for(i=1;i<=9;i++)
  	for(j=1;j<=9;j++)
  	sum+=Get(i,j)*ans[i][j];
  	Ans=max(Ans,sum);
    return;
  }
  int i;
  if(!ans[x][y])
  {
    for(i=1;i<=9;i++)
    if(boo_x[x][i]&&boo_y[y][i]&&boo_QAQ[check(x,y)][i])
    {
  	  boo_x[x][i]=0;boo_y[y][i]=0;boo_QAQ[check(x,y)][i]=0;
  	  ans[x][y]=i;
  	  if(y!=9)
  	  DFS(x,y+1);else DFS(Next[x],1);
  	  boo_x[x][i]=1;boo_y[y][i]=1;boo_QAQ[check(x,y)][i]=1;
  	  ans[x][y]=0;
    }
  }
  else
  {if(y!=9)DFS(x,y+1);else DFS(Next[x],1);}
}
int main()
{
  for(i=1;i<=9;i++)
  for(j=1;j<=9;j++)
  boo_x[i][j]=1,boo_y[i][j]=1,boo_QAQ[i][j]=1,QwQ[i].num=i;
  for(i=1;i<=9;i++)
  for(j=1;j<=9;j++)
  {
    cin>>ans[i][j];
    boo_x[i][ans[i][j]]=0;
    boo_y[j][ans[i][j]]=0;
    boo_QAQ[check(i,j)][ans[i][j]]=0;
    if(!ans[i][j])QwQ[i].sum++;
  }
  sort(QwQ+1,QwQ+10,cmp);
  for(i=1;i<=10;i++)
  Next[QwQ[i].num]=QwQ[i+1].num;
  Next[QwQ[9].num]=10;
  Next[0]=QwQ[1].num;
  DFS(Next[0],1);
  if(!Ans)cout<<-1;else
  cout<<Ans;
} 

不用多解释了吧QAQ
下面才是重点 因为这个代码长
其实主要代码也差不多QAQ

这是一个读入:

char Get()
{
  char ch=' ';
  while(ch!='v'&&ch!='^'&&ch!='<'&&ch!='>')ch=getchar();
  return ch;
}

这是一坨读入:

  char ch;
  for(i=1;i<=3;i++)
  {
  	for(j=1;j<=3;j++)
  	{
  	  ch=Get();
  	  if(ch=='<')
  	  {
  	    boo_QwQ[i*3-3+1][j*3-3+1][i*3-3+1][j*3-3+2]=-1;
  	    boo_QwQ[i*3-3+1][j*3-3+2][i*3-3+1][j*3-3+1]=1;	
	  }
  	  if(ch=='>')
  	  {
  	    boo_QwQ[i*3-3+1][j*3-3+1][i*3-3+1][j*3-3+2]=1;
  	    boo_QwQ[i*3-3+1][j*3-3+2][i*3-3+1][j*3-3+1]=-1;	
	  }
	  ch=Get();
	  if(ch=='>')
  	  {
  	    boo_QwQ[i*3-3+1][j*3-3+3][i*3-3+1][j*3-3+2]=-1;
  	    boo_QwQ[i*3-3+1][j*3-3+2][i*3-3+1][j*3-3+3]=1;	
	  }
  	  if(ch=='<')
  	  {
  	    boo_QwQ[i*3-3+1][j*3-3+3][i*3-3+1][j*3-3+2]=1;
  	    boo_QwQ[i*3-3+1][j*3-3+2][i*3-3+1][j*3-3+3]=-1;	
	  }
	}
	for(j=1;j<=3;j++)
	{
	  ch=Get();
	  if(ch=='^')
	  {
	    boo_QwQ[i*3-3+1][j*3-3+1][i*3-3+2][j*3-3+1]=-1;
	    boo_QwQ[i*3-3+2][j*3-3+1][i*3-3+1][j*3-3+1]=1;
	  }
	  if(ch=='v')
	  {
	    boo_QwQ[i*3-3+1][j*3-3+1][i*3-3+2][j*3-3+1]=1;
	    boo_QwQ[i*3-3+2][j*3-3+1][i*3-3+1][j*3-3+1]=-1;
	  }
	  ch=Get();
	  if(ch=='^')
	  {
	    boo_QwQ[i*3-3+1][j*3-3+2][i*3-3+2][j*3-3+2]=-1;
	    boo_QwQ[i*3-3+2][j*3-3+2][i*3-3+1][j*3-3+2]=1;
	  }
	  if(ch=='v')
	  {
	    boo_QwQ[i*3-3+1][j*3-3+2][i*3-3+2][j*3-3+2]=1;
	    boo_QwQ[i*3-3+2][j*3-3+2][i*3-3+1][j*3-3+2]=-1;
	  }
	  ch=Get();
	  if(ch=='^')
	  {
	    boo_QwQ[i*3-3+1][j*3-3+3][i*3-3+2][j*3-3+3]=-1;
	    boo_QwQ[i*3-3+2][j*3-3+3][i*3-3+1][j*3-3+3]=1;
	  }
	  if(ch=='v')
	  {
	    boo_QwQ[i*3-3+1][j*3-3+3][i*3-3+2][j*3-3+3]=1;
	    boo_QwQ[i*3-3+2][j*3-3+3][i*3-3+1][j*3-3+3]=-1;
	  }
    }
  	for(j=1;j<=3;j++)
  	{
  	  ch=Get();
  	  if(ch=='<')
  	  {
  	    boo_QwQ[i*3-3+2][j*3-3+1][i*3-3+2][j*3-3+2]=-1;
  	    boo_QwQ[i*3-3+2][j*3-3+2][i*3-3+2][j*3-3+1]=1;	
	  }
  	  if(ch=='>')
  	  {
  	    boo_QwQ[i*3-3+2][j*3-3+1][i*3-3+2][j*3-3+2]=1;
  	    boo_QwQ[i*3-3+2][j*3-3+2][i*3-3+2][j*3-3+1]=-1;	
	  }
	  ch=Get();
	  if(ch=='>')
  	  {
  	    boo_QwQ[i*3-3+2][j*3-3+3][i*3-3+2][j*3-3+2]=-1;
  	    boo_QwQ[i*3-3+2][j*3-3+2][i*3-3+2][j*3-3+3]=1;	
	  }
  	  if(ch=='<')
  	  {
  	    boo_QwQ[i*3-3+2][j*3-3+3][i*3-3+2][j*3-3+2]=1;
  	    boo_QwQ[i*3-3+2][j*3-3+2][i*3-3+2][j*3-3+3]=-1;	
	  }
	}
	for(j=1;j<=3;j++)
	{
	  ch=Get();
	  if(ch=='^')
	  {
	    boo_QwQ[i*3-3+2][j*3-3+1][i*3-3+3][j*3-3+1]=-1;
	    boo_QwQ[i*3-3+3][j*3-3+1][i*3-3+2][j*3-3+1]=1;
	  }
	  if(ch=='v')
	  {
	    boo_QwQ[i*3-3+2][j*3-3+1][i*3-3+3][j*3-3+1]=1;
	    boo_QwQ[i*3-3+3][j*3-3+1][i*3-3+2][j*3-3+1]=-1;
	  }
	  ch=Get();
	  if(ch=='^')
	  {
	    boo_QwQ[i*3-3+2][j*3-3+2][i*3-3+3][j*3-3+2]=-1;
	    boo_QwQ[i*3-3+3][j*3-3+2][i*3-3+2][j*3-3+2]=1;
	  }
	  if(ch=='v')
	  {
	    boo_QwQ[i*3-3+2][j*3-3+2][i*3-3+3][j*3-3+2]=1;
	    boo_QwQ[i*3-3+3][j*3-3+2][i*3-3+2][j*3-3+2]=-1;
	  }
	  ch=Get();
	  if(ch=='^')
	  {
	    boo_QwQ[i*3-3+2][j*3-3+3][i*3-3+3][j*3-3+3]=-1;
	    boo_QwQ[i*3-3+3][j*3-3+3][i*3-3+2][j*3-3+3]=1;
	  }
	  if(ch=='v')
	  {
	    boo_QwQ[i*3-3+2][j*3-3+3][i*3-3+3][j*3-3+3]=1;
	    boo_QwQ[i*3-3+3][j*3-3+3][i*3-3+2][j*3-3+3]=-1;
	  }
    }
    for(j=1;j<=3;j++)
  	{
  	  ch=Get();
  	  if(ch=='<')
  	  {
  	    boo_QwQ[i*3-3+3][j*3-3+1][i*3-3+3][j*3-3+2]=-1;
  	    boo_QwQ[i*3-3+3][j*3-3+2][i*3-3+3][j*3-3+1]=1;	
	  }
  	  if(ch=='>')
  	  {
  	    boo_QwQ[i*3-3+3][j*3-3+1][i*3-3+3][j*3-3+2]=1;
  	    boo_QwQ[i*3-3+3][j*3-3+2][i*3-3+3][j*3-3+1]=-1;	
	  }
	  ch=Get();
	  if(ch=='>')
  	  {
  	    boo_QwQ[i*3-3+3][j*3-3+3][i*3-3+3][j*3-3+2]=-1;
  	    boo_QwQ[i*3-3+3][j*3-3+2][i*3-3+3][j*3-3+3]=1;	
	  }
  	  if(ch=='<')
  	  {
  	    boo_QwQ[i*3-3+3][j*3-3+3][i*3-3+3][j*3-3+2]=1;
  	    boo_QwQ[i*3-3+3][j*3-3+2][i*3-3+3][j*3-3+3]=-1;	
	  }
	}
  }

四维数组用来放两个位置哪个大,哪个小

即 boo_QAQ[x1][y1][x2][y2]=1就是ans[x1][y1]必须大于ans[x2][y2]
同理-1就是小于

可能有点费空间QAQ

判断这个数的可行性的时候只要加上这么一段:

bool Check(int x,int y/*传入的位置*/,int num/*传入的数字*/)
{
  int i;
  for(i=1;i<=4;i++)//判断这个位置的这个数的当前可行性
  if(boo_QwQ[x][y][x+z1[i]][y+z2[i]]==1)//这个数大于旁边的哪个数
  {
  	if(ans[x+z1[i]][y+z2[i]])
  	{
  	  if(num<=ans[x+z1[i]][y+z2[i]])return 0;//不符合
	}
  }else
  if(boo_QwQ[x][y][x+z1[i]][y+z2[i]]==-1)//小于
  {
  	if(ans[x+z1[i]][y+z2[i]])
  	{
  	  if(num>=ans[x+z1[i]][y+z2[i]])return 0;//不符合
	}
  }
  return 1;//符合了QAQ
}

接下来还是上一个完整的代码吧:

#include<bits/stdc++.h>
using namespace std;
int i,j,k,n,Len=0,ans[11][11],boo_QwQ[11][11][11][11];
int Num[50];
bool boo_x[10][10],boo_y[10][10],boo_QAQ[10][10];
int check(int x,int y)
{return (y-1)/3+1+((x-1)/3)*3;}
int z1[5]={0,1,-1,0,0};
int z2[5]={0,0,0,1,-1};
bool Check(int x,int y,int num)
{
  int i;
  for(i=1;i<=4;i++)
  if(boo_QwQ[x][y][x+z1[i]][y+z2[i]]==1)
  {
  	if(ans[x+z1[i]][y+z2[i]])
  	{
  	  if(num<=ans[x+z1[i]][y+z2[i]])return 0;	
	}
  }else
  if(boo_QwQ[x][y][x+z1[i]][y+z2[i]]==-1)
  {
  	if(ans[x+z1[i]][y+z2[i]])
  	{
  	  if(num>=ans[x+z1[i]][y+z2[i]])return 0;
	}
  }
  return 1;
}
char Get()
{
  char ch=' ';
  while(ch!='v'&&ch!='^'&&ch!='<'&&ch!='>')ch=getchar();
  return ch;
}
void DFS(int x,int y)
{
  if(x==10)
  {
  	int i,j;
  	for(i=1;i<=9;i++)
  	{
  	  for(j=1;j<=9;j++)
  	  cout<<ans[i][j]<<" ";
  	  cout<<endl;
	}
	exit(0);
  }
  int i;
  if(!ans[x][y])
  {
    for(i=1;i<=9;i++)
    if(boo_x[x][i]&&boo_y[y][i]&&boo_QAQ[check(x,y)][i]&&Check(x,y,i))
    {
  	  boo_x[x][i]=0;boo_y[y][i]=0;boo_QAQ[check(x,y)][i]=0;
  	  ans[x][y]=i;
  	  if(y!=9)
  	  DFS(x,y+1);else DFS(x+1,1);
  	  boo_x[x][i]=1;boo_y[y][i]=1;boo_QAQ[check(x,y)][i]=1;
  	  ans[x][y]=0;
    }
  }
  else
  {if(y!=9)DFS(x,y+1);else DFS(x+1,1);}
}
int main()
{
  for(i=1;i<=9;i++)
  for(j=1;j<=9;j++)
  boo_x[i][j]=1,boo_y[i][j]=1,boo_QAQ[i][j]=1;
  char ch;
  for(i=1;i<=3;i++)
  {
  	for(j=1;j<=3;j++)
  	{
  	  ch=Get();
  	  if(ch=='<')
  	  {
  	    boo_QwQ[i*3-3+1][j*3-3+1][i*3-3+1][j*3-3+2]=-1;
  	    boo_QwQ[i*3-3+1][j*3-3+2][i*3-3+1][j*3-3+1]=1;	
	  }
  	  if(ch=='>')
  	  {
  	    boo_QwQ[i*3-3+1][j*3-3+1][i*3-3+1][j*3-3+2]=1;
  	    boo_QwQ[i*3-3+1][j*3-3+2][i*3-3+1][j*3-3+1]=-1;	
	  }
	  ch=Get();
	  if(ch=='>')
  	  {
  	    boo_QwQ[i*3-3+1][j*3-3+3][i*3-3+1][j*3-3+2]=-1;
  	    boo_QwQ[i*3-3+1][j*3-3+2][i*3-3+1][j*3-3+3]=1;	
	  }
  	  if(ch=='<')
  	  {
  	    boo_QwQ[i*3-3+1][j*3-3+3][i*3-3+1][j*3-3+2]=1;
  	    boo_QwQ[i*3-3+1][j*3-3+2][i*3-3+1][j*3-3+3]=-1;	
	  }
	}
	for(j=1;j<=3;j++)
	{
	  ch=Get();
	  if(ch=='^')
	  {
	    boo_QwQ[i*3-3+1][j*3-3+1][i*3-3+2][j*3-3+1]=-1;
	    boo_QwQ[i*3-3+2][j*3-3+1][i*3-3+1][j*3-3+1]=1;
	  }
	  if(ch=='v')
	  {
	    boo_QwQ[i*3-3+1][j*3-3+1][i*3-3+2][j*3-3+1]=1;
	    boo_QwQ[i*3-3+2][j*3-3+1][i*3-3+1][j*3-3+1]=-1;
	  }
	  ch=Get();
	  if(ch=='^')
	  {
	    boo_QwQ[i*3-3+1][j*3-3+2][i*3-3+2][j*3-3+2]=-1;
	    boo_QwQ[i*3-3+2][j*3-3+2][i*3-3+1][j*3-3+2]=1;
	  }
	  if(ch=='v')
	  {
	    boo_QwQ[i*3-3+1][j*3-3+2][i*3-3+2][j*3-3+2]=1;
	    boo_QwQ[i*3-3+2][j*3-3+2][i*3-3+1][j*3-3+2]=-1;
	  }
	  ch=Get();
	  if(ch=='^')
	  {
	    boo_QwQ[i*3-3+1][j*3-3+3][i*3-3+2][j*3-3+3]=-1;
	    boo_QwQ[i*3-3+2][j*3-3+3][i*3-3+1][j*3-3+3]=1;
	  }
	  if(ch=='v')
	  {
	    boo_QwQ[i*3-3+1][j*3-3+3][i*3-3+2][j*3-3+3]=1;
	    boo_QwQ[i*3-3+2][j*3-3+3][i*3-3+1][j*3-3+3]=-1;
	  }
    }
  	for(j=1;j<=3;j++)
  	{
  	  ch=Get();
  	  if(ch=='<')
  	  {
  	    boo_QwQ[i*3-3+2][j*3-3+1][i*3-3+2][j*3-3+2]=-1;
  	    boo_QwQ[i*3-3+2][j*3-3+2][i*3-3+2][j*3-3+1]=1;	
	  }
  	  if(ch=='>')
  	  {
  	    boo_QwQ[i*3-3+2][j*3-3+1][i*3-3+2][j*3-3+2]=1;
  	    boo_QwQ[i*3-3+2][j*3-3+2][i*3-3+2][j*3-3+1]=-1;	
	  }
	  ch=Get();
	  if(ch=='>')
  	  {
  	    boo_QwQ[i*3-3+2][j*3-3+3][i*3-3+2][j*3-3+2]=-1;
  	    boo_QwQ[i*3-3+2][j*3-3+2][i*3-3+2][j*3-3+3]=1;	
	  }
  	  if(ch=='<')
  	  {
  	    boo_QwQ[i*3-3+2][j*3-3+3][i*3-3+2][j*3-3+2]=1;
  	    boo_QwQ[i*3-3+2][j*3-3+2][i*3-3+2][j*3-3+3]=-1;	
	  }
	}
	for(j=1;j<=3;j++)
	{
	  ch=Get();
	  if(ch=='^')
	  {
	    boo_QwQ[i*3-3+2][j*3-3+1][i*3-3+3][j*3-3+1]=-1;
	    boo_QwQ[i*3-3+3][j*3-3+1][i*3-3+2][j*3-3+1]=1;
	  }
	  if(ch=='v')
	  {
	    boo_QwQ[i*3-3+2][j*3-3+1][i*3-3+3][j*3-3+1]=1;
	    boo_QwQ[i*3-3+3][j*3-3+1][i*3-3+2][j*3-3+1]=-1;
	  }
	  ch=Get();
	  if(ch=='^')
	  {
	    boo_QwQ[i*3-3+2][j*3-3+2][i*3-3+3][j*3-3+2]=-1;
	    boo_QwQ[i*3-3+3][j*3-3+2][i*3-3+2][j*3-3+2]=1;
	  }
	  if(ch=='v')
	  {
	    boo_QwQ[i*3-3+2][j*3-3+2][i*3-3+3][j*3-3+2]=1;
	    boo_QwQ[i*3-3+3][j*3-3+2][i*3-3+2][j*3-3+2]=-1;
	  }
	  ch=Get();
	  if(ch=='^')
	  {
	    boo_QwQ[i*3-3+2][j*3-3+3][i*3-3+3][j*3-3+3]=-1;
	    boo_QwQ[i*3-3+3][j*3-3+3][i*3-3+2][j*3-3+3]=1;
	  }
	  if(ch=='v')
	  {
	    boo_QwQ[i*3-3+2][j*3-3+3][i*3-3+3][j*3-3+3]=1;
	    boo_QwQ[i*3-3+3][j*3-3+3][i*3-3+2][j*3-3+3]=-1;
	  }
    }
    for(j=1;j<=3;j++)
  	{
  	  ch=Get();
  	  if(ch=='<')
  	  {
  	    boo_QwQ[i*3-3+3][j*3-3+1][i*3-3+3][j*3-3+2]=-1;
  	    boo_QwQ[i*3-3+3][j*3-3+2][i*3-3+3][j*3-3+1]=1;	
	  }
  	  if(ch=='>')
  	  {
  	    boo_QwQ[i*3-3+3][j*3-3+1][i*3-3+3][j*3-3+2]=1;
  	    boo_QwQ[i*3-3+3][j*3-3+2][i*3-3+3][j*3-3+1]=-1;	
	  }
	  ch=Get();
	  if(ch=='>')
  	  {
  	    boo_QwQ[i*3-3+3][j*3-3+3][i*3-3+3][j*3-3+2]=-1;
  	    boo_QwQ[i*3-3+3][j*3-3+2][i*3-3+3][j*3-3+3]=1;	
	  }
  	  if(ch=='<')
  	  {
  	    boo_QwQ[i*3-3+3][j*3-3+3][i*3-3+3][j*3-3+2]=1;
  	    boo_QwQ[i*3-3+3][j*3-3+2][i*3-3+3][j*3-3+3]=-1;	
	  }
	}
  }
  DFS(1,1);
} 

恐怖的代码…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值