好久没做题感觉自己越来越菜了。。从头开始刷kuangbin叭
https://vjudge.net/contest/65959#overview
题目链接如上
poj 1321 棋盘问题
首先可以选用二维搜索
#include<stdio.h>
#include<iostream>
#include<string.h>
int a[30];
bool b[30];
int qipan[10][10];//2代表不可访问,0代表空可访问,1代表已经占位
int n,k;
int count=0;
int num;
void init()
{
char c;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(int i=0;i<n;i++)
{
getchar();
for(int j=0;j<n;j++)
{
scanf("%c",&c);
if(c=='#') qipan[i][j]=0;
else if(c=='.')
{
qipan[i][j]=2;
}
}
}
count=0;
}
void hs(int l,int m)
{
if(m>=k)
{
count++;
return;
}
for(int lnow=l;lnow<n;lnow++)
{
//if(a[lnow]==false)
//{
//a[lnow]=true;
for(int i=0;i<=n-1;i++)
{
if(b[i]==false&&qipan[lnow][i]==0)
{
b[i]=true;
qipan[lnow][i]=1;
hs(lnow+1,m+1);
b[i]=false;
qipan[lnow][i]=0;
}
}
//a[lnow]=false;
//}
}
}
/*void hs(int l)
{
if(l>=n)
return;
if(num>=k)
{
count++;
return;
}
for(int i=0;i<n;i++)
{
if(b[i]==false && qipan[l][i]==0)
{
b[i]=true;
num++;
hs(l+1);
b[i]=false;
num--;
}
}
}*/
using namespace std;
int main()
{
while(scanf("%d%d",&n,&k) && (n!=-1 ||k!=-1))
{
init();
hs(0,0);
cout<<count<<endl;
}
return 0;
}
做题的时候要想明白这个回溯过程是不需要a数组的,因为按照行l来进行,就保证了行不会重复。
记得不断修改qipan
还有就是一个直接hs一个的,但是这个需要注意上面两个if的顺序,刚开始写的一直是反着的导致结果不够
(两种其实原理差不多叭感觉emmm。。。)
#include<stdio.h>
#include<iostream>
#include<string.h>
//int a[30];
bool b[30];
int qipan[10][10];//2代表不可访问,0代表空可访问,1代表已经占位
int n,k;
int count=0;
int num;
void init()
{
char c;
//memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(int i=0;i<n;i++)
{
getchar();
for(int j=0;j<n;j++)
{
scanf("%c",&c);
if(c=='#') qipan[i][j]=0;
else if(c=='.')
{
qipan[i][j]=2;
}
}
}
count=0;
}
/*void hs(int l,int m)
{
if(m>=k)
{
count++;
return;
}
for(int lnow=l;lnow<n;lnow++)//这个位置保证了行不会超,但是下面那种是可能超的
{
//if(a[lnow]==false)
//{
//a[lnow]=true;
for(int i=0;i<=n-1;i++)
{
if(b[i]==false&&qipan[lnow][i]==0)
{
b[i]=true;
qipan[lnow][i]=1;
hs(lnow+1,m+1);
b[i]=false;
qipan[lnow][i]=0;
}
}
//a[lnow]=false;
//}
}
}*/
void hs(int l)
{
if(num>=k)
{
count++;
return;//当最后一个被安排在最后一行,l+1必定会超,这时候可能有答案的so。。
}
if(l>=n)
return;
for(int i=0;i<n;i++)
{
if(b[i]==false && qipan[l][i]==0)
{
b[i]=true;
qipan[l][i]=1;
num++;
hs(l+1);
qipan[l][i]=0;
b[i]=false;
num--;
}
}
hs(l+1);//代表没有放置棋子,不修改num,但是行数加一
}
using namespace std;
int main()
{
while(scanf("%d%d",&n,&k) && (n!=-1 ||k!=-1))
{
init();
num=0;
hs(0);
cout<<count<<endl;
}
return 0;
}
注意DFS和BFS的使用场合,DFS适合求出路径和具体信息,BFD适合求出最短路径和长度。(别人博客说的,存)
https://www.cnblogs.com/joeylee97/p/6128310.html