2016 UESTC Traing Search Algorithm &String Problem N 简单的双向搜索

来源:互联网 发布:淘宝微淘评论设置 编辑:程序博客网 时间:2024/05/15 08:39

题目链接:点击打开链接

N - 简单的双向搜索

Time Limit: 2000/1000MS (Java/Others)     Memory Limit: 131072/131072KB (Java/Others)

给定三个大小为N的整型数组A1,A2,A3,和三个整数B1,B2,B3。接下来依次做N次操作:对于第i次操作(i=1,2,..,N),选择一个数j(j=1,2,3),令Bj加上Aj[i]。问是否存在一种操作序列,使得最后B1=B2=B3=0

Input

第一行四个数N(1<=N<=25),B1,B2,B3。接下来N行,每行三个整数,表示A1[i],A2[i]A3[i]。保证|A1[i]|,|A2[i]|,|A3[i]|,|B1|,|B2|,|B3|<=109

Output

如果存在符合要求的方案,输出"YES";否则输出"NO"


这是双向搜索的入门题,也是经典的选数问题,双向bfs相对于单向bfs无论是在时间还是空间复杂度上都优于单向bfs,bfs实际上任然是一种盲目搜索算法,它考虑完一个层次后,才会考虑下一个层次,所以状态数成指数级增长,对空间消耗非常大,如果已知目标状态,我们考虑使用双向bfs,空间消耗在指数上大约能减少一半;对于这道题,由于这不是一道求最短路的问题,而是一道判断题,所以我们不需要记忆化搜索,我们先正向走n/2步,此时,用map保存,反向走n-n/2步,查此时的状态是否在map中出现过。

#include<bits/stdc++.h>using namespace std;int a[3][30];struct node1{int b[3];int step;};vector<int>v;map<vector<int>,int>m3;queue<node1>q1;queue<node1>q2;int main(){int b[3],n,i,j,k;scanf("%d %d %d %d",&n,&b[0],&b[1],&b[2]);for(i=0;i<n;i++)for(j=0;j<3;j++)scanf("%d",&a[j][i]);struct node1 sta,des;for(i=0;i<3;i++)sta.b[i]=b[i];sta.step=0;for(j=0;j<3;j++)des.b[j]=0;des.step=0;q1.push(sta);q2.push(des);struct node1 x,y;v.resize(3);while(1){if(!q1.empty())//正向走n/2步 {x=q1.front();if(x.step==n/2)break;q1.pop();for(i=0;i<3&&x.step<n;i++){y=x;y.b[i]+=a[i][y.step];y.step++;if(y.step==n/2)//存入容器中 {v[0]=y.b[0];v[1]=y.b[1];v[2]=y.b[2];m3[v]=1;continue;}q1.push(y);}}elsebreak;}while(1){if(!q2.empty())//反向走n-n/2步 {x=q2.front();if(x.step>n-n/2){printf("NO");return 0;}q2.pop();for(i=0;i<3&&x.step<n;i++){y=x;y.b[i]-=a[i][n-y.step-1];y.step++;if(y.step==n-n/2)//比较 {v[0]=y.b[0];v[1]=y.b[1];v[2]=y.b[2];if(m3.count(v)){printf("YES");return 0;}continue;}q2.push(y);}}else{printf("NO");return 0;}}return 0;}


0 0
原创粉丝点击