ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c++搜索

2021-09-19 21:30:02  阅读:140  来源: 互联网

标签:int dfs 占位 flag maxn c++ 搜索 b1


  更新下c++中搜索算法,用在一般算法竞赛中是DFS和BFS。当然,一些启发式搜索,例如遗传算法,模拟退火等。一般算法竞赛中不会涉及。
DFS:

//算法框架
void dfs(int n){
   if(搜索结束){
      记录结果。
      return;
   }
   for(遍历所有解){
       if(合法的解){
         占位。
    }
       dfs(n+1);
       取消占位。
  }
}

算法框架如上,对于一些简单的问题,相当于填空了。
经典例题N皇后
上代码87分,超时代码

#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=15;
int N,cnt,a[maxn][maxn];
void dfs(int n){
	if(n==N+1){//递归结束
		if(cnt<3){ //满足条件输出前三组解
			for(int i=1;i<=N;i++){
				for(int j=1;j<=N;j++){
					if(a[i][j]==1){
						cout<<j<<" ";
						break;
					}
				}
			}
			cout<<endl;
		}
		cnt++;
		return;
}
	for(int i=1;i<=N;i++){ //遍历每一行所有可能结果
		int flag=1;
	    for(int j=0;(n-j)>=1;j++){ //向上寻找
	    	if(a[n-j][i]==1){
	    		flag=0;
	    		break;
			}
		}
		if(!flag) continue; //上方已经有皇后 
		for(int j=1;(n-j)>=1&&(i+j)<=N;j++){//右上方寻找
			if(a[n-j][i+j]==1){
	    		flag=0;
	    		break;				
			}
		}
		if(!flag) continue;
		for(int j=1;(n-j)>=1&&(i-j)>=1;j++){//左上方寻找
			if(a[n-j][i-j]==1){
	    		flag=0;
	    		break;				
			}
		}
		if(!flag) continue;
		if(flag){ //可以占位
		    a[n][i]=1; //占位		    
			dfs(n+1);//寻找下一层
	        a[n][i]=0;	//取消占位
		} 	
}
	return ;
}
int main(){
	cin>>N;
	dfs(1);
	cout<<cnt;
	return 0;
}

  上面的代码是正确的,只不过在n=13的时候,运行时间是1.2s超时了,是TLE没有AC。思路很简单,用二维数组,模拟棋盘。因为每行,列以及两条对角线不能放皇后。因此,用递归的层数表示行也就是变量n,所有的解就是每一列也就是变量i,每次放皇后时,检查每一列,以及对角线,满足要求就放下,否则继续搜索。
弄清变量n,i的含义,理清思路即可。
  好久不练了,不难的一道题写了两个版本共计2个半小时。。。
接着,上AC代码,二维变一维,智商被碾压。

#include<cstdio>
using namespace std;
const int maxn=100;
int a[maxn],n,ans=0;
int b1[maxn],b2[maxn],b3[maxn];
void dfs(int x){
    if(x>n){
      ans++;
      if(ans<=3){
         for(int i=1;i<=n;i++){
             printf("%d ",a[i]);
         }
         puts(" ");
      }
      return;
    }
    for(int i=1;i<=n;i++){
        if(b1[i]==0&&b2[i]==0&&b3[i]==0){
            a[x]=i;
            b1[i]=1;b2[x+i]=1;b3[x-i+15]=1;
            dfs(x+1);
            b1[i]=0;b2[x+i]=0;b3[x-i+15]=0;
        }
    }
}
int main(){
    scanf("%d",&n);
    dfs(1);
    printf("%d",ans);
    return 0;
}

  代码用三个数组表示每一列,以及两条对角线。对于列来说,它的y是定值,对于两条对角线,x+y或者x-y是定值。由于x-y可能会小于0,用偏移量16保证大于0,即可。

标签:int,dfs,占位,flag,maxn,c++,搜索,b1
来源: https://blog.csdn.net/Pbw_666/article/details/120384647

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有