蓝桥杯 PREV-19 九宫重排 (BFS + hash)
2017-04-02 20:27
281 查看
题目链接:http://lx.lanqiao.cn/problem.page?gpid=T42
解题方案:
一共9!=362880种状态,爆搜不会超时。
刚开始用dfs,刚开始直接用dir记录上一层到本层所走的方向,目的是想要防止走回头路。结果:爆栈。
经过调试发现这样只能避免立即走回头路,并不能防止走环路。
于是发现还是要写vis数组进行标记,但是本题的状态是一个图,或者说是一个字符串,前一种视角不方便hash从而记录状态是否访问过,用字符串描述本题的状态的话,就可以用map<string,int>来记录,用成员函数find()来查找,方便地实现vis数组的功能了,这时候就不需要用dir记录上一次走的方向了。
改完以后,结果:爆栈。。
又调了好久发现爆栈并不是因为有死循环,而是真的递归的深度太深了,本题用dfs的确是会爆栈的。。貌似用#pragma comment(linker, "/STACK:1024000000,1024000000")手动加栈提交到蓝桥杯的OJ也没用??
所以还是改成bfs了。
爆栈的dfs代码
擦着时限过的bfs代码(900多ms)
解题方案:
一共9!=362880种状态,爆搜不会超时。
刚开始用dfs,刚开始直接用dir记录上一层到本层所走的方向,目的是想要防止走回头路。结果:爆栈。
经过调试发现这样只能避免立即走回头路,并不能防止走环路。
于是发现还是要写vis数组进行标记,但是本题的状态是一个图,或者说是一个字符串,前一种视角不方便hash从而记录状态是否访问过,用字符串描述本题的状态的话,就可以用map<string,int>来记录,用成员函数find()来查找,方便地实现vis数组的功能了,这时候就不需要用dir记录上一次走的方向了。
改完以后,结果:爆栈。。
又调了好久发现爆栈并不是因为有死循环,而是真的递归的深度太深了,本题用dfs的确是会爆栈的。。貌似用#pragma comment(linker, "/STACK:1024000000,1024000000")手动加栈提交到蓝桥杯的OJ也没用??
所以还是改成bfs了。
爆栈的dfs代码
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string> #include <cmath> #include <vector> #include <queue> #include <stack> #include <set> #include <map> using namespace std; #define FOR(i,k,n) for(int i=k;i<n;i++) #define FORR(i,k,n) for(int i=k;i<=n;i++) #define scan(a) scanf("%d",&a) #define scann(a,b) scanf("%d%d",&a,&b) #define scannn(a,b,c) scanf("%d%d%d",&a,&b,&c) #define mst(a,n) memset(a,n,sizeof(a)) #define ll long long #define N 1005 #define mod 1000000007 #define INF 0x3f3f3f3f const double eps=1e-8; const double pi=acos(-1.0); char s[10],e[10]; int ans; int go[4]={-3,1,3,-1}; map<string,int> mp; void Dfs(int step,int dir) { //printf("第%d层 之前方向为%d\n",step,dir); if(strcmp(s,e)==0) { ans=min(ans,step); return ; } int p=-1; for(int i=0;s[i];i++) { if(s[i]=='.') { p=i; break; } } for(int i=0;i<4;i++) { if(abs(i-dir)==2) continue; if(p%3==2&&i==1) continue; if(p%3==0&&i==3) continue; int adj=p+go[i]; if(adj>=0&&adj<9) { //printf("%c与%c互换\n",s[adj],s[p]); swap(s[adj],s[p]); //printf("互换之后%s\n",s); if(mp.find(s)==mp.end()) { mp[s]=1; Dfs(step+1,i); } //else printf("*************出现相同状态*************\n"); swap(s[adj],s[p]); } } } int main() { //freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); ans=INF; scanf("%s%s",s,e); //printf("%s\n%s",s,e); mp[s]=1; Dfs(0,-10); printf("%d\n",ans); return 0; }
擦着时限过的bfs代码(900多ms)
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string> #include <cmath> #include <vector> #include <queue> #include <stack> #include <set> #include <map> using namespace std; #define FOR(i,k,n) for(int i=k;i<n;i++) #define FORR(i,k,n) for(int i=k;i<=n;i++) #define scan(a) scanf("%d",&a) #define scann(a,b) scanf("%d%d",&a,&b) #define scannn(a,b,c) scanf("%d%d%d",&a,&b,&c) #define mst(a,n) memset(a,n,sizeof(a)) #define ll long long #define N 1005 #define mod 1000000007 #define INF 0x3f3f3f3f const double eps=1e-8; const double pi=acos(-1.0); string s,e; int go[4]={-3,1,3,-1}; map<string,int> mp; struct node { string str; int step; node(string a,int b) { str=a; step=b; } }; int Bfs() { queue<node> q; mp[s]=1; q.push(node(s,0)); while(!q.empty()) { node cur=q.front(); q.pop(); if(cur.str==e) { return cur.step; } int p=-1; string now=cur.str; for(int i=0;now[i];i++) { if(now[i]=='.') { p=i; break; } } for(int i=0;i<4;i++) { if(p%3==2&&i==1) continue; if(p%3==0&&i==3) continue; int adj=p+go[i]; if(adj>=0&&adj<9) { swap(now[adj],now[p]); if(mp.find(now)==mp.end()) { mp[now]=1; q.push(node(now,cur.step+1)); } swap(now[adj],now[p]); } } } return -1; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); cin>>s>>e; printf("%d\n",Bfs()); return 0; }
相关文章推荐
- 蓝桥杯_PREV-19_九宫重排 【双广搜】
- 蓝桥杯历届试题——九宫重排(bfs)
- 蓝桥杯 九宫重排(BFS)
- 蓝桥杯 历届试题 九宫重排 (八数码问题--康托展开去重 + bfs搜索)
- 蓝桥杯 历届试题 九宫重排(bfs)
- 蓝桥杯 历届试题 九宫重排 BFS Java
- 蓝桥杯 历届试题 九宫重排 解题报告(BFS,双向BFS优化)
- 蓝桥杯——九宫重排(八数码问题)
- 蓝桥杯 九宫重排(八数码问题)
- 第四届蓝桥杯决赛题-九宫重排(双向广搜).java
- 蓝桥杯OJ PREV-19 九宫重排
- 蓝桥杯【历届试题】九宫重排
- 第四届蓝桥杯决赛题-九宫重排(双向广搜).java
- 蓝桥杯 九宫重排
- 蓝桥杯 九宫重排
- 蓝桥杯-历届试题-九宫重排-BFS+剪枝
- 蓝桥杯, 历届试题 九宫重排 (八数码)
- 蓝桥杯- 九宫重排
- 蓝桥杯 历届试题 九宫重排
- 蓝桥杯 历届试题 九宫重排(双向搜索优化)