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 < ...
随机推荐
- Excel等外部程序点击链接会带上IE信息的bug
今天碰到一个问题,在Excel内点击链接到默认浏览器Chrome打开,奇怪的是服务端收到的Session一直对不上. 查了很久发现这个Excel到Chrome的跳转竟然带上了IE的Cookie 和 U ...
- PHP之验证码识别
首先推荐几篇有关验证码识别的文章,觉得不错 php实现验证码的识别(初级篇) 关于bp神经网格识别验证码 一.思路 碰见一个验证码,如果我们想要识别它,我们需要的是做什么呢? 我们先观察几个验证码.. ...
- Android输入法开发
1. 概念 * IMF: 输入法框架(Input Method Framework) * IM: 输入法(Input Method) * IMS: 输入法服务(Input Method Service ...
- newman安装时遇到问题的解决
npm安装newman时系统提示需要安装.net framwork环境 通过查询文档安装visual studio express: 于是安装visual studio 2012 express. 安 ...
- Django Web在Apache上的部署
1. 安装配置Apache 2. 安装wsgi_mod模块 3. 开放相应端口 vim /etc/sysconfig/iptables # Firewall configuration written ...
- c# 無彈窗调用打印机
using System; using System.Collections.Generic; using System.Text; using System.Configuration; using ...
- 安装 mysql server
三个月前向公司申请了一台服务器单独给我用,作为部署我写的自动发布工具的服务器.同事不久前在我这台服务器上装了个数据库,今天上去查了一下,用不了,只有information_schema和test两个数 ...
- Windows Phone 学习笔记(一) 数据存储
独立存储设置IsolatedStorageSetting private IsolatedStorageSettings _appSettings; public MainPage() { Initi ...
- 开源java
http://code.google.com/p/nullpomino/source/checkout http://www.open-open.com/open254058.htm http://w ...
- java的"=="与"equals"
equals 方法是 java.lang.Object 类的方法. 有两种用法说明: (1)对于字符串变量来说,使用“==”和“equals()”方法比较字符串时,其比较方法不同. “==”比较两个变 ...