POJ 1184 聪明的打字员
简直难到没朋友。
双向bfs + 剪枝。
剪枝策略:
对于2--5位置上的数,仅仅有当光标在相应位置时通过swap ,up。down来改变。那么当当前位置没有达到目标状态时,left和right无意义。
好了。仅仅剪掉这里就过掉了。。。
还有比較炫酷的方法实现枚举720种排列。
。。
然后状压什么的。。。
功力不够全然看不懂。
。。。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <stack>
#include <map> #pragma comment(linker, "/STACK:1024000000");
#define EPS (1e-8)
#define LL long long
#define ULL unsigned long long
#define _LL __int64
#define _INF 0x3f3f3f3f
#define Mod 9999991 using namespace std; short int mark[1000000][7][2]; struct Q
{
int ans,sta,site,fl;
}; int s[10]; int pre[] = {1000000,100000,10000,1000,100,10,1};
// 0 1 2 3 4 5 6
inline int Cal(int num,int site,int ch)
{
int temp = (num/pre[site])%10 + ch;
if(0 <= temp && temp <= 9)
return num/pre[site-1]*pre[site-1] + temp*pre[site] + num%pre[site];
return num;
} inline int Swap(int num,int site,int m)
{
int t1 = (num/pre[site])%10;
int t2 = (num/pre[m])%10; if(t1 == t2)
return num; num = num/pre[site-1]*pre[site-1] + t2*pre[site] + num%pre[site];
num = num/pre[m-1]*pre[m-1] + t1*pre[m] + num%pre[m];
return num;
} bool Judge(int site,int a,int b)
{
if((a/pre[site])%10 == (b/pre[site])%10)
return true;
return false;
} int bfs(int a,int b)
{
memset(mark,-1,sizeof(mark)); queue<Q> q;
Q s,t; s.sta = a;
s.fl = 0;
s.ans = 0;
s.site = 1; mark[s.sta][s.site][s.fl] = 0;
q.push(s); s.sta = b;
s.ans = 0;
s.fl = 1; for(int i = 1;i <= 6; ++i)
{
s.site = i;
mark[s.sta][s.site][s.fl] = 0;
q.push(s);
} while(q.empty() == false)
{
t = q.front();
q.pop(); // printf("site = %2d sta = %6d fl = %2d ans = %2d\n",t.site,t.sta,t.fl,t.ans); if(mark[t.sta][t.site][t.fl^1] != -1)
{
return mark[t.sta][t.site][t.fl^1] + t.ans;
} s.fl = t.fl;
s.ans = t.ans+1; //left
s.sta = t.sta; if(t.site > 1 && (t.site < 2 || t.site > 5 || Judge(t.site,t.sta,t.fl == 0 ? b : a)))
{
s.site = t.site-1;
if(mark[s.sta][s.site][s.fl] == -1)
{
mark[s.sta][s.site][s.fl] = s.ans;
q.push(s);
}
} //right
if(t.site < 6 && (t.site < 2 || t.site > 5 || Judge(t.site,t.sta,t.fl == 0 ? b : a)))
{
s.site = t.site+1;
if(mark[s.sta][s.site][s.fl] == -1)
{
mark[s.sta][s.site][s.fl] = s.ans;
q.push(s);
}
} //up
s.sta = Cal(t.sta,t.site,1);
s.site = t.site;
if(mark[s.sta][s.site][s.fl] == -1)
{
mark[s.sta][s.site][s.fl] = s.ans;
q.push(s);
} //down
s.sta = Cal(t.sta,t.site,-1); if(mark[s.sta][s.site][s.fl] == -1)
{
mark[s.sta][s.site][s.fl] = s.ans;
q.push(s);
} //swap0
if(t.site != 1)
{
s.sta = Swap(t.sta,t.site,1); if(mark[s.sta][s.site][s.fl] == -1)
{
mark[s.sta][s.site][s.fl] = s.ans;
q.push(s);
}
} //swap1
if(t.site != 6)
{
s.sta = Swap(t.sta,t.site,6);
if(mark[s.sta][s.site][s.fl] == -1)
{
mark[s.sta][s.site][s.fl] = s.ans;
q.push(s);
}
}
}
return 0;
} int main()
{
//freopen("data.txt","r",stdin);
int a,b;
scanf("%d %d",&a,&b);
printf("%d\n",bfs(a,b)); return 0;
}
POJ 1184 聪明的打字员的更多相关文章
- (广搜)聪明的打字员 -- POJ --1184
链接: http://poj.org/problem?id=1184 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=88230#probl ...
- poj1184 聪明的打字员(BFS剪枝)
http://poj.org/problem?id=1184 用字符串s存下数字,并把光标位置做一个字符加到s末尾,用map做标记状态是否出现过,然后bfs即可. 不剪枝是过不了的,考虑的两种交换操作 ...
- 聪明的打字员---poj1184(bfs)
题目链接:http://poj.org/problem?id=1184 分析:首先可以发现有6*10^6种状态,比较多,不过搜索的时候可以去除一些无用的状态, 可以发现一个点的值(2-5)如果想要改变 ...
- poj 1184 广搜进阶题
起初的想法果然就是一个6000000的状态的表示. 但是后面觉得还是太过于幼稚了. 可以看看网上的解释,其实就是先转换位置,然后再改变数字的大小. #include<iostream> # ...
- codevs 1733 聪明的打字员 (Bfs)
/* Bfs+Hash 跑的有点慢 但是codevs上时间限制10s 也ok */ #include<iostream> #include<cstdio> #include&l ...
- poj 1184
经典的宽搜题目,感觉最好的办法应该是双向广搜. 不过用简单的启发式搜索可以飘过. #include <iostream> #include <cstdio> #include ...
- poj练习题的方法
poj1010--邮票问题 DFSpoj1011--Sticks dfs + 剪枝poj1020--拼蛋糕poj1054--The Troublesome Frogpoj1062--昂贵的聘礼poj1 ...
- poj很好很有层次感(转)
OJ上的一些水题(可用来练手和增加自信) (POJ 3299,POJ 2159,POJ 2739,POJ 1083,POJ 2262,POJ 1503,POJ 3006,POJ 2255,POJ 30 ...
- POJ题目分类推荐 (很好很有层次感)
著名题单,最初来源不详.直接来源:http://blog.csdn.net/a1dark/article/details/11714009 OJ上的一些水题(可用来练手和增加自信) (POJ 3299 ...
随机推荐
- 为什么要用BitSet
BitSet适用于一类型boolean判断,Java的BitSet在这类型判断中非常高效. 举例说明:在判断前2000万数字中素数个数的程序中,如果使用最基本的素数判断代码: package com; ...
- netduino第一步,环境配置
在netduino.com的官网介绍下,我很快就入门,现在的最新netduino的版本是4.3,但4.3是运行在win8下的,在codeplex.net上有,大部分人还使用的是win7,因此我现在采用 ...
- Java描述语言、国家和地理的类——Locale
Locale类代表一个特定的地理.语言和国家环境.一个Locale的实例对象本身不会验证它代表的语言和国家地区信息是否正确,只是向一些对国家和语言.地理等比较敏感的类提供国家地区语言信息,这些类有Da ...
- Android 环境变量配置(Mac)
Mac 系统10.10,自带的就是jdk1.6,因为工作需要就升级到了1.7,要从新配置环境变量了 mac 默认是自带的有jdk1.6 安装路径为: /System/Library/Framework ...
- 几个前端博客 good
http://www.cnblogs.com/JustinYoung/archive/2011/02/24/fresh-free-html-templates-2010.html http://www ...
- Swift - 浮点数转换成整数(四舍五入与直接截断)
1,直接截去小数部分转换成整数 使用强制转换会将浮点部分去除,把整数部分转换为整数. 1 var i = Int(23.50) //23 2,四舍五入转换成整数 lroundf是一个全局函数,作用是将 ...
- 做SEO推广必须要做的9件事儿
SEO推广是由网站优化网络运营媒体宣传结合的一种技术,而现在恰好就是媒体最为流行,真因为如此很多的站长之知道利用自媒体推广网站,结果推广了几年网站权重只有2到3而已,导致和谐问题的关键就是没有结合其他 ...
- IE浏览器上传文件时本地路径变成”C:\fakepath\”的问题
在使用<input id="file_upl" type="file" />控件上传文件时,有时会需要获取文件本地路径展示给客户,这时可以通过这样的 ...
- Spring MVC 数据验证——validate注解方式
1.说明 学习注解方式之前,应该先学习一下编码方式的spring注入.这样便于理解验证框架的工作原理.在出错的时候,也能更好的解决这个问题.所以本次博客教程也是基于编码方式.仅仅是在原来的基础加上注解 ...
- Delphi默认窗体随想
Delphi中新建一个Form或者Frame时,它的字体都是西文习惯,这样就有可能造成在其他机器上由于字体的原因,窗体十分不美观.怎样才能为Delphi设置一个默认窗体,让它的字体Font符合中国习惯 ...