///数独
1.3*3的判断
2.很多if-------怎么回溯二维棋盘+有预设,不填
3.这个没设初始值,要设就加个输入给res
#include <iostream>
#include<bits/stdc++.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
#define maxn 10000
int sum=0;
int fin =9;
int res[maxn][maxn]={0};
///panduan
int isvalid(int m,int n,int num)
{
for(int i=1;i<=fin;i++)///列内是否重复
{
if(res[m][i]==num)
{
return 0;
}
}
for(int i=1;i<=fin;i++)
{
if(res[i][n]==num)
{
return 0;
}
}
for(int i=1;i<=fin;i++)///3*3方格
{
///3*3非常恶心,但也有意思 if (board[(r/3)*3 + i/3][(c/3)*3 + i%3] == n)这个是0,0开始的,下面是1,1开始的
if(res[ ((m-1)/3)*3 + (i-1)/3 + 1 ][ ((n-1)/3)*3 +(i-1)%3 +1 ]==num)
{
return 0;
}
}
return 1;
}
void backtrack(int m,int n)
{
if(m==fin&&n>fin)
{
for(int i=1;i<=fin;i++)
{
for(int j=1;j<=fin;j++)
{
cout<<res[i][j]<<" ";
}
cout<<endl;
}
sum++;
cout<<"sum="<<sum;
cout<<endl;
return ;
}
if(n>fin)///一行填完,下一行
{
backtrack(m+1,0);
return ;
}
if(res[m][n]!=0)///有预设,不填
{
backtrack(m,n+1);
return ;
}
for(int i=1;i<=fin;i++)
{
if(!isvalid(m,n,i))
{
continue;
}
res[m][n]=i;
backtrack(m,n+1);
res[m][n]=0;
}
}
int main(int argc, char** argv) {
res[3][3]=1;
backtrack(1,1);
return 0;
}
2021.3.9复习
重点在于怎么遍历(换行)
第28-33行非常重要,不是硬置,而是开新遍历
另外跳过已知条件,应放在遍历可行解之前,并在if内递归
只找一个可行解的话:可以利用return true 找到可行解直接结束,具体看gitbook
中间有if判断,阻断继续遍历,很重要
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define maxn 1000005
int res[10][10];
int isvalid(int x,y,a)
{
}
int neednum(int x,y)
{
}
int fin=9;
///重点在于怎么遍历(换行)
void traceback()
{
if(x>fin)
{
//存储或输出
return ;
}
if(y>fin)
{
// y=1;
// x+=1;
///非常重要,不是硬置,而是开新遍历
traceback(x+1,1);
}
if(res[x][y]!=0)///有数了,跳过的应该放在遍历之前
{
traceback(x,y+1);
}
for(int i=1;i<=fin;i++)
{
//if(neednum(x,y)&&!isvalid(x,y,a))continue;///
///这里写的也有问题,那碰上不能填的,就直接完结了
///跳过的应该放在遍历之前
if(!isvalid(x,y,a))continue;
res[x][y]=i;
traceback(x,y+1);///重点
res[x][y]=0;
}
}
///另外只找一个可行解,可以利用return true 找到可行解直接结束,具体看gitbook
///(中间有if判断,阻断继续遍历,很重要)
int main()
{
return 0;
}