题目地址: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. 一种实现C++反射功能的想法(二)

    在介绍我的思路前, 让我们准备下预备知识 C++是怎么实现类函数的绑定的. 我们知道类的非静态成员函数是存储在全局区, 并在内存中只保存一份副本. 我们调用非静态成员函数是通过类对象进行调用. 那么如 ...

  2. 【POJ2352】【树状数组】Stars

    Description Astronomers often examine star maps where stars are represented by points on a plane and ...

  3. js中的潜伏者之Arguments对象

    argument 说明: 在JavaScript中,arguments是对象的一个特殊属性.arguments对象就像数组,但是它却不是数组.可以理解为他是潜伏者,通俗的说,就是你传的参数不一定按照参 ...

  4. 响应式十日谈第一日:使用 rem 设置文字大小

    上面回顾: 在序言中我们已经提到了响应式的一些基本理念,比如: 响应式网页不仅仅是响应不同类型的设备,而且需要响应不同的用户需求.响应式的初衷是为了让信息更好的传递交流,让所有人无障碍的获取信息,同时 ...

  5. cocod2d-x 之 CCTMXTiledMap & CCTMXLayer

    cocos2dx框架自带的地图CCTMXTiledMap,继承自CCNode.CCTMXTiledMap的坐标系的原点位于左上角,以一个瓦片为单位,换句话说,左上角第一块瓦片的坐标为(0,0),而紧挨 ...

  6. php基础知识【函数】(8)xml和变量函数

     一.XML函数 参数类型 data    --string,需要解析的数据集. parser  --resource,一个指向要取得字节索引的 XML 解析器的引用.  1.创建和释放XMl解析器 ...

  7. plot的实践。

    from matplotlib import pyplot as plt data = np.loadtxt(r'C:\Users\yinggang\Desktop\1\a.txt') x,y,z = ...

  8. HTML部分标签的含义(2)

    1,ul标签,添加新闻信息列表 使用ul标签,信息无先后顺序 这些列表就可以用ul-li标签来完成 语法:<ul> <li>信息</li> <li>信息 ...

  9. c#解析xml字符串 分析 EntityName 时出错

    因为xml字符串中的特殊html字符被转义了,怎么防止转义呢,可以在xml内加上<![CDATA[返回内容]] 这样可以防止特殊字符被转义,就好像微信公共平台消息传递也都是xml格式他们也都加& ...

  10. App的token机制

    这只是网上看来的后期可能还会修改. 理论版的描述如下: (1) 服务器接收到app发送的用户名和密码后,验证用户名和密码是否正确. 如果错误则返回错误信息. 如果验证正确,生成一个随机的不重复的tok ...