2017暑假集训 div1 搜索进阶(1)
来源:互联网 发布:最优化方法推荐 编辑:程序博客网 时间:2024/06/06 01:11
HDU 1560 (IDA*)
题意:给少于八个的DNA序列,问使 DNA 序列为其子串的序列最短多长?
做法:第一次做这种迭代加深搜的题,就看了大牛们的博客。
说说我的理解把:深搜之所以效率不高是因为它是一种盲目的搜索(俗称一路走到黑)。那么如果我们限制它说能走到的层数,如果在该层没有找到,加层数加一接着向下找,就会节省时间。
1.首先取所有子串中最长的为初始深度
2.做 DFS 剪枝 (1).如果当前层数超越限制层数
(2).用f(h)函数来估计最佳情况,那么h就是 当前的长度 加上 所有串中剩余最多的长度。 进入剪枝1
3. 如果没有满足题意,限制深度++,重复2操作!
注意:这里的状态开了个8的数组表示每个串匹配到什么位置。
代码:
#include <iostream>#include <stdio.h>#include <algorithm>#include <string.h>#include <queue>using namespace std;char str[10][10];char dna[4]={'A','C','G','T' };int ans, n,deep=0;void dfs(int now,int len[10]){ if(now>deep) return; int h=0; for(int i=0;i<n;++i) { int temp= strlen(str[i])-len[i]; h=max(h,temp); } if(h==0) { ans=now; return ;} if(h+now>deep) return ; for(int i=0;i<4;++i) { bool flag=0; int pos[10]={0}; for(int j=0;j<n;++j) { if(str[j][len[j]]==dna[i]) { flag=1; pos[j]=len[j]+1; } else pos[j]=len[j]; } if(flag) dfs(now+1,pos); if(ans!=-1) return; }}int main(){ int T; scanf("%d",&T); while(T--) { deep=0; ans=-1; scanf("%d",&n); for(int i=0;i<n;++i) { scanf("%s",str[i]); int temp=strlen(str[i]); deep=max(deep,temp); } int pos[10]={0}; while(1) { dfs(0,pos); if(ans!=-1) break; deep++; } printf("%d\n",ans); } return 0;}
HDU 3085 双向BFS
题意: 输入n*m的字符矩阵,矩阵中的 M 速度 是3格/m, G的速度是1格/m,Z是鬼,初始有两个,每秒可以变出很多的分身Z(变出的分身在下一秒钟仍然可以变出无数个分身),占领跟Z距离是2的方格,直到占领所有的方格,每次都是鬼先占领方格,然后是M跟G走,M跟G可以同时都走,也可以有一个在原地不动,一个在走。
做法:解锁了新姿势原来做BFS的时候都是一条路走到黑没有讨论过天数。
关键:每次调用BFS先用size存下原来队列里的节点个数,每次拓展的时候把这些节点弹完就结束
1.M 每次走三步 就BFS三天即可 ,G 走一步 就BFS一遍即可
2.判断鬼因为可以穿墙所以直接用 当前点与鬼的距离(X+Y )与 2*time 的关系即可判断
代码:
#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>#include <queue>#include <math.h>using namespace std;struct node{ int x,y;}z[2],mm,gg;char map[805][805];int n,m;bool vis[2][805][805];queue<node> q[2];int step=0;int dir[4][2]={1,0, -1,0, 0,-1, 0,1 };int judge(struct node a){ if(a.x<0||a.x>=n||a.y<0||a.y>=m) return 0; if( map[a.x][a.y]=='X' ) return 0; if( (abs(z[0].x-a.x)+abs(z[0].y-a.y))<=2*step ) return 0; if( (abs(z[1].x-a.x)+abs(z[1].y-a.y))<=2*step ) return 0; return 1;}int bfs(int w){ node u,v; int sum=q[w].size(); while(sum--) { u=q[w].front(); q[w].pop(); if(judge(u)==0) continue; for(int i=0;i<4;++i) { v.x=u.x+dir[i][0]; v.y=u.y+dir[i][1]; if(judge(v)==0) continue; if(!vis[w][v.x][v.y]) { if(vis[w^1][v.x][v.y]) return 1; vis[w][v.x][v.y]=1; q[w].push(v); } } } return 0;}int work(){ while(!q[0].empty()) q[0].pop(); while(!q[1].empty()) q[1].pop(); memset(vis,0,sizeof(vis)); q[0].push(mm); vis[0][mm.x][mm.y]=1; q[1].push(gg); vis[1][gg.x][gg.y]=1; step=0; while ((!q[0].empty()) || (!q[1].empty())) { step++; if(bfs(0)) return step; if(bfs(0)) return step; if(bfs(0)) return step; if(bfs(1)) return step; } return -1;}int main(){ int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); int znum=0; for(int i=0;i<n;++i) scanf("%s",map[i]); for(int i=0;i<n;++i) { for(int j=0;j<m;++j) { if(map[i][j]=='M') {mm.x=i;mm.y=j;} if(map[i][j]=='G') {gg.x=i;gg.y=j;} if(map[i][j]=='Z') {z[znum].x=i; z[znum++].y=j;} } } printf("%d\n",work()); } return 0;}
- 2017暑假集训 div1 搜索进阶(1)
- 2017暑假集训 div1 DP(1)
- 2017暑假集训 div1 简单搜索
- 2017暑假集训 div1 最短路(1)
- 2017暑假集训 div1 并查集(1)
- 2017暑假集训 div1 最小生成树(1)
- 2017暑假集训 div1 线段树(1)
- 2017暑假集训 div1 连通图(1) POJ3694 &&POJ3177
- 2017暑假集训 div1 匹配问题(1)
- 2017暑假集训 div1 匹配问题(1)
- 2017暑假集训 div1 DP(2)
- 2017暑假集训 div1 最短路(2)
- 2017暑假集训 div1 最短路(3)
- 2017暑假集训 div1 并查集(2)
- 2017暑假集训 div1 线段树(2)
- 2017暑假集训 div1 连通图(2)
- 暑假集训--训练1 二分搜索
- 【暑假集训专题#搜索】
- bzoj1231: [Usaco2008 Nov]mixup2 混乱的奶牛
- validatebox.js
- 1880: [Sdoi2009]Elaxia的路线
- 共用体和结构体所占内存大小的计算方法二
- Ajax如何设置同步请求
- 2017暑假集训 div1 搜索进阶(1)
- ARM体系结构
- 安装JDK后出现 只能运行JAVA不能运行JAVAC
- 新浪微博发表内容ajax拼接
- 设计模式-Singleton模式(只有一个实例)
- Android studio如何更改应用程序的图标以及名称
- 【算法】座位排序算法
- android开发之动画效果
- jzoj 3452_长方形_模拟