POJ1184-------操作分离的BFS
题目地址:http://poj.org/problem?id=1184
题目意思:
给你两个6位数,一个是起始值,一个最终值
初始光标在最左边
你可以左移或者右移光变
在光标处+1或者-1
在光标处和最左边或者和最右边交换
问你最少要多少就可以由初始值转换到最终值
解题思路:
操作分离是解决这题的核心思想
就是说我们反正要进行一些转换的,不如先全部转换了算了
通过一个BFS预处理将所有可能转换的全部转换,光标所有可能的位置全部求出来
然后在每次要求的时候,对每种状态上的光标进行加减操作
求出最少的步骤
另外这题的测试数据有问题,其实左移也是需要的
比如000159 和 000519,正确答案是8,如果不考虑左移就是12
再就是我们可以将光标的访问情况压缩到10种,具体的在我代码中有解释
下面上代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<string>
#include<map>
#include<queue>
using namespace std; struct node
{
int state;
int pos;
int num[6];
int step;
int fangwen[6];
}; int vis_state[10][6] =
{
1,0,0,0,0,0, /*访问状态0: 初始状态(pos=0)*/
1,1,0,0,0,0, /*访问状态1: 状态0通过右移操作得到(pos=1),或者状态1通过swap0操作得到(pos=1)*/
1,1,1,0,0,0, /*访问状态2: 状态1通过右移操作得到(pos=2),或者状态2通过swap0操作得到(pos=2)*/
1,1,1,1,0,0, /*访问状态3: 状态2通过右移操作得到(pos=3),或者状态3通过swap0操作得到(pos=3)*/
1,1,1,1,1,0, /*访问状态4: 状态3通过右移操作得到(pos=4),或者状态4通过swap0操作得到(pos=4)*/
1,0,0,0,0,1, /*访问状态5: 状态0通过swap1操作得到(pos=0),或者状态5通过swap0操作得到(pos=0)*/
1,1,0,0,0,1, /*访问状态6: 状态1通过swap1操作得到(pos=1),或者状态5通过右移操作得到(pos=1),或者状态6通过swap0操作得到(pos=1)*/
1,1,1,0,0,1, /*访问状态7: 状态2通过swap1操作得到(pos=2),或者状态6通过右移操作得到(pos=2),或者状态7通过swap0操作得到(pos=2)*/
1,1,1,1,0,1, /*访问状态8: 状态3通过swap1操作得到(pos=3),或者状态7通过右移操作得到(pos=3),或者状态8通过swap0操作得到(pos=3)*/
1,1,1,1,1,1 /*访问状态9: 状态4通过swap1操作得到(pos=4),或者状态8通过右移操作得到(pos=4),或者状态9通过右移操作得到(pos=5),
或者状态4通过右移操作得到(pos=5),或者状态9通过swap0操作得到,或者状态9通过swap1操作得到*/
}; int state[10000][8]; //对应的是所有情况,第二维记录相应信息 int idx;
int co; bool vis[6][6][6][6][6][6][6][10]; //前6个是数字,为什么只到6,是因为这个是做排列用的
//第7个是光标所在位置用的,第8个事state void put_to_vis(node a)
{
vis[a.num[0]][a.num[1]][a.num[2]][a.num[3]][a.num[4]][a.num[5]][a.pos][a.state] = true;
} bool check(node a)
{
return vis[a.num[0]][a.num[1]][a.num[2]][a.num[3]][a.num[4]][a.num[5]][a.pos][a.state];
} int find_state(node a)
{
if(a.fangwen[5]==0)
{
int cnt = 0;
for(int i=1;i<5;i++)
if(a.fangwen[i])
cnt++;
return cnt;
}
else
{
int cnt = 0;
for(int i=1;i<5;i++)
if(a.fangwen[i])
cnt++;
return cnt+5;
}
} void bfs()
{
queue<node> Q;
node a,b;
idx=0;
co=0;
for(int i=0;i<6;i++)
{
a.num[i] = i;
a.fangwen[i] = 0;
} a.pos = a.state = a.step = 0;
a.fangwen[0] = 1;
Q.push(a);
put_to_vis(a); //printf("a step %d\n",a.step);
int co2=0; while(!Q.empty())
{
co++;
a = Q.front();
Q.pop(); for(int i=0;i<6;i++)
state[idx][i] = a.num[i];
state[idx][6] = a.state;
state[idx][7] = a.step;
idx++; if(a.pos>0) //左移或者左交换操作
{
//左移操作
b=a;
b.step = a.step+1;
b.pos--;
if(!check(b))
{
put_to_vis(b);
Q.push(b);
} //左交换
b = a;
b.step = a.step+1;
swap(b.num[0],b.num[b.pos]);
if(!check(b))
{
put_to_vis(b);
Q.push(b);
}
} if(a.pos<5) //右移和右交换操作
{
//右移
b=a;
b.step = a.step+1;
b.pos++;
b.fangwen[b.pos] = 1;
b.state = find_state(b);
if(!check(b))
{
put_to_vis(b);
Q.push(b);
} //右交换
b = a ;
b.step = a.step+1;
swap(b.num[5],b.num[b.pos]);
b.fangwen[5] = 1;
b.state = find_state(b);
if(!check(b))
{
put_to_vis(b);
Q.push(b);
}
}
}
} int main()
{
memset(vis,false,sizeof(vis));
bfs();
char st[10];
char ed[10];
int _st[6];
int _ed[6];
while(scanf("%s%s",st,ed) != EOF)
{
for(int i=0;i<6;i++)
{
_st[i] = st[i]-'0';
_ed[i] = ed[i]-'0';
} int ans = 99999999; for(int i=0;i<idx;i++)
{
int tmp = state[i][7];//初始化为进行了交换后的步数
bool flag = true;
int j;
for(j=0;j<6;j++)
{
if(!vis_state[state[i][6]][j] && (_st[state[i][j]]!=_ed[j]) )
{
flag = false;
break;
}
else
{
tmp += abs( _st[state[i][j]] - _ed[j]); //再加上每位进行加减 操作的步数
}
} if(flag)
ans = min(ans,tmp); }
printf("%d\n",ans);
}
return 0;
}
POJ1184-------操作分离的BFS的更多相关文章
- 基于ASP.NET Core 3.x的端点路由(Endpoint Routing)实现控制器(Controller)和操作(Action)分离的接口服务
本文首发于 码友网 -- <基于ASP.NET Core 3.x的端点路由(Endpoint Routing)实现控制器(Controller)和操作(Action)分离的接口服务> 前言 ...
- SQL Server读写分离实现方案简介
读写分离是中型规模应用的数据库系统常见设计方案,通过将数据从主服务器同步到其他从服务器,提供非实时的查询功能,扩展性能并提高并发性. 数据库的读写分离的好处如下: 通过将“读”操作和“写”操作分离到不 ...
- Sicily 1048: Inverso(BFS)
题意是给出一个3*3的黑白网格,每点击其中一格就会使某些格子的颜色发生转变,求达到目标状态网格的操作.可用BFS搜索解答,用vector储存每次的操作 #include<bits/stdc++. ...
- Sicily 1444: Prime Path(BFS)
题意为给出两个四位素数A.B,每次只能对A的某一位数字进行修改,使它成为另一个四位的素数,问最少经过多少操作,能使A变到B.可以直接进行BFS搜索 #include<bits/stdc++.h& ...
- 读写分离提高 SQL Server 并发性能
以下内容均非原创,仅作学习.分享!! 在 一些大型的网站或者应用中,单台的SQL Server 服务器可能难以支撑非常大的访问压力.很多人在这时候,第一个想到的就是一个解决性能问题的利器——负载均衡. ...
- POJ 3414 Pots【bfs模拟倒水问题】
链接: http://poj.org/problem?id=3414 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22009#probl ...
- win7+SQL2008无法打开物理文件 操作系统错误 5:拒绝访问 SQL Sever
今天在win7+SQL2008的环境下操作分离附加数据库,分离出去然后再附加,没有问题.但是一把.mdf文件拷到其它文件夹下就出错,错误如下:无法打开物理文件 "E:\db\MyDB.mdf ...
- SQL server 分离数据库与删除数据库的区别
今天,在sql server 中,分离数据库,然后就问了一下,与删除数据库的区别 区别在于(百度一下): 分离后,.mdb和.log文件都在,以后你需要用的时候,还可以用附加数据库的方法加上去,分离数 ...
- hdu 5652 India and China Origins 二分+bfs
题目链接 给一个图, 由01组成, 1不能走. 给q个操作, 每个操作将一个点变为1, 问至少多少个操作之后, 图的上方和下方不联通. 二分操作, 然后bfs判联通就好了. #include < ...
随机推荐
- SGU 153.Playing with matches
题意: 一个取火柴游戏,可以取的数在一个集合S内,S必包含1,且不超过9个数,每个数都不大于9.最后取完者失败. 求n(n<10^9)根火柴时先取的胜利还是后取的胜利. Solution: 典型 ...
- 《vi中的替换艺术》-linux命令五分钟系列之十一
vi方面的内容不知道分类到哪里好,就放到<Linux命令五分钟系列>里吧! 今天编程,关于栈的一个小例子,其间我需要把”S.”替换为”S->”(替换不包括双引号). 其实这个不难,不 ...
- jQuery-弹窗登录
在jQuery中实现弹窗常要用到的方法有: width() :元素的宽度 outerWidth() 元素的宽度 盒子的padding+border 总的宽度 scrollTop() 鼠标滚轮自上 ...
- SVN更新失败,提示locked
使用SVN更新资源时,提示locked,解决方案如下: 首先找到是哪个文件不能进行更新/提交,在本地工作区间中找到这个文件对应的目录,目录里面会有.svn文件夹,这个文件夹默认是隐藏的,需要设置文件夹 ...
- MapReduce程序开发之流量求和(八)
1.分析记录手机流量的日志. 2.拿到日志中的一行数据,切分各个字段,抽取出我们需要的字段:手机号,上行流量,下行流量,然后封装成kv发送出去 3.使用java中的map方法: public clas ...
- SharePoint 2013 弹窗效果之本地HTML打开方式(二)
上一篇我们主要讲述如何通过showModalDialog方法进行弹出窗体,同时弹出信息定义在新的页面(Application Page),使用 SP.UI.$create_DialogOptions( ...
- 三种常见字符编码简介:ASCII、Unicode和UTF-8
什么是字符编码? 计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是255( ...
- Gray码 (格雷码) 【二进制】
以下内容是看了Matrix67的关于二进制的blog(Link)的一点总结与摘录. Gray码,中文“格雷码”,是一种特殊的编码,相邻两个格雷码的二进制表示中有且仅有一位不同,且 n 阶 Gray 码 ...
- codeforces D. Long Path
http://codeforces.com/contest/408/problem/D 题意:有一排房间每个房间有两扇门,一扇通往第i+1个房间,另一扇通往第p[i]个房间,(p[i]<=i)然 ...
- ASP.NET最常用的页面生命周期事件
PreInit:在页生命周期的早期阶段可以访问的事件.在PreInit事件后,将加载个性化信息和页主题. Init:在所有的控件都已初始化,且已应用所有外观设置后引发.使用该事件来读取或初始化控件属性 ...