题目地址: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的更多相关文章

  1. 基于ASP.NET Core 3.x的端点路由(Endpoint Routing)实现控制器(Controller)和操作(Action)分离的接口服务

    本文首发于 码友网 -- <基于ASP.NET Core 3.x的端点路由(Endpoint Routing)实现控制器(Controller)和操作(Action)分离的接口服务> 前言 ...

  2. SQL Server读写分离实现方案简介

    读写分离是中型规模应用的数据库系统常见设计方案,通过将数据从主服务器同步到其他从服务器,提供非实时的查询功能,扩展性能并提高并发性. 数据库的读写分离的好处如下: 通过将“读”操作和“写”操作分离到不 ...

  3. Sicily 1048: Inverso(BFS)

    题意是给出一个3*3的黑白网格,每点击其中一格就会使某些格子的颜色发生转变,求达到目标状态网格的操作.可用BFS搜索解答,用vector储存每次的操作 #include<bits/stdc++. ...

  4. Sicily 1444: Prime Path(BFS)

    题意为给出两个四位素数A.B,每次只能对A的某一位数字进行修改,使它成为另一个四位的素数,问最少经过多少操作,能使A变到B.可以直接进行BFS搜索 #include<bits/stdc++.h& ...

  5. 读写分离提高 SQL Server 并发性能

    以下内容均非原创,仅作学习.分享!! 在 一些大型的网站或者应用中,单台的SQL Server 服务器可能难以支撑非常大的访问压力.很多人在这时候,第一个想到的就是一个解决性能问题的利器——负载均衡. ...

  6. POJ 3414 Pots【bfs模拟倒水问题】

    链接: http://poj.org/problem?id=3414 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22009#probl ...

  7. win7+SQL2008无法打开物理文件 操作系统错误 5:拒绝访问 SQL Sever

    今天在win7+SQL2008的环境下操作分离附加数据库,分离出去然后再附加,没有问题.但是一把.mdf文件拷到其它文件夹下就出错,错误如下:无法打开物理文件 "E:\db\MyDB.mdf ...

  8. SQL server 分离数据库与删除数据库的区别

    今天,在sql server 中,分离数据库,然后就问了一下,与删除数据库的区别 区别在于(百度一下): 分离后,.mdb和.log文件都在,以后你需要用的时候,还可以用附加数据库的方法加上去,分离数 ...

  9. hdu 5652 India and China Origins 二分+bfs

    题目链接 给一个图, 由01组成, 1不能走. 给q个操作, 每个操作将一个点变为1, 问至少多少个操作之后, 图的上方和下方不联通. 二分操作, 然后bfs判联通就好了. #include < ...

随机推荐

  1. android查看真机中的数据库

    0.在有网的前提下1.安装 Android Studio,Lantern,Chrome浏览器2.在在githab上搜索stetho,打开第一个facebook/stetho3.在Gradle Scri ...

  2. CSS的inherit与auto使用分析

    一个很显浅的寓言,千年老树,电打雷劈,屹立不倒,却毁于蝼蚁的侵袭之下.自以为精通CSS的人,常常被一些小问题搞到头晕脑胀. 通常是一个很小的数值,经过层层放大歪曲后,整个布局就走形了.CSS是一门很简 ...

  3. sphinx(coreseek)——1、增量索引

    首先介绍一下     CoreSeek/Sphinx的发布包 indexer: 用于创建全文索引;    search: 一个简单的命令行(CLI) 的测试程序,用于测试全文索引;    search ...

  4. 基于Jquery+Ajax+Json实现分页显示

    1.后台action产生json数据. List blackList = blackService.getBlackInfoList(mobileNum, gatewayid, startDate, ...

  5. ubuntu 安装 open in teminal

    sudo apt-get install nautilus-open-terminalnautilus -q

  6. EntityFramework - Migrations

    EntityFramework  - Migrations 對項目進行EF的數據庫升級操作.分爲開發環境與部署環境.上的操作總結. 引用: Command說明https://coding.abel.n ...

  7. java枚举小结

    如何定义一个枚举类? //定义了4个等级 enum Level{ A,B,C,D } 枚举类的实质: class Level{ public static final Level A = new Le ...

  8. jquery $(this).attr $(this).val方法使用介绍--useful

    $(this).attr(key); 获取节点属性名的值,相当于getAttribute(key)方法,本文整理了一些相关的示例,感兴趣的朋友可以参考下 $(this).attr(key); 获取节点 ...

  9. [BZOJ 1048] [HAOI2007] 分割矩阵 【记忆化搜索】

    题目链接:BZOJ - 1048 题目分析 感觉这种分割矩阵之类的题目很多都是这样子的. 方差中用到的平均数是可以直接算出来的,然后记忆化搜索 Solve(x, xx, y, yy, k) 表示横坐标 ...

  10. [BZOJ 1816] [Cqoi2010] 扑克牌 【二分答案】

    题目链接:BZOJ - 1816 题目分析 答案具有可以二分的性质,所以可以二分答案. 验证一个答案 x 是否可行,就累加一下各种牌相对于 x 还缺少的量,如果总和超过了 x 或 m ,就不可行. 因 ...