首页 > 代码库 > 2014 Super Training #6 G Trim the Nails --状态压缩+BFS
2014 Super Training #6 G Trim the Nails --状态压缩+BFS
原题: ZOJ 3675 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3675
由m<=20可知,可用一个二进制数表示指甲的状态,最多2^20,初始状态为0,表示指甲都没剪,然后BFS找解,每次枚举剪刀的两个方向,枚举移动的位数进行扩展状态即可。
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <queue>using namespace std;#define N 10007struct node{ int state,step; node(int _state,int _step) { state = _state; step = _step; } node(){}};int vis[1<<21];int cut[2]; //两个方向queue<node> que;int n,m;int bfs(int s){ int i,j,k; memset(vis,0,sizeof(vis)); while(!que.empty()) que.pop(); int E = (1<<m)-1; que.push(node(s,0)); vis[s] = 1; while(!que.empty()) { node tmp = que.front(); que.pop(); int state = tmp.state; int step = tmp.step; int tms = state; for(i=0;i<2;i++) //direction { for(j=0;j<n;j++) //move { int end = ((cut[i]>>j) | tms) & E; // &E : keep m bit if(vis[end]) continue; vis[end] = 1; if(end == E) return step+1; que.push(node(end,step+1)); } for(j=0;j<m;j++) { int to = ((cut[i]<<j) | tms) & E; if(vis[to]) continue; vis[to] = 1; if(to == E) return step+1; que.push(node(to,step+1)); } } } return -1;}int main(){ int i,j; char ss[13]; while(scanf("%d",&n)!=EOF) { cut[0] = cut[1] = 0; scanf("%s",ss); for(i=0;i<=n;i++) { if(ss[i] == ‘*‘) { cut[0] |= (1<<i); cut[1] |= (1<<(n-1-i)); } } scanf("%d",&m); if(cut[0] == 0) { puts("-1"); continue; } printf("%d\n",bfs(0)); } return 0;}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。