题意:给你一个串,仅含有a~g,且每个字母只出现最多一次。和一个光标初始位置,以及一个目标串,问你最少要多少的代价变化成目标串。

有五种操作:在光标前添加一个未出现过的字母,代价1。

删除光标前或者光标后的字母,代价1。

光标左移或者右移,代价0.5。

哈希,把串弄成一个八进制数,加上一个光标位置,状态数不超过8^8。

直接跑dijkstra即可。

要注意初始化的时候,可以单独记一个数组,表示用过的状态,仅仅重置这些状态,防止初始化复杂度过高。

#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
char s1[10],s2[10];
int pp,len1,len2,d[17000000],pw[10];
bool vis[17000000],cant[8];
int st[17000000],En;
struct Node{
int u,d;
Node(const int &u,const int &d){
this->u=u;
this->d=d;
}
Node(){}
};
bool operator < (const Node &a,const Node &b){
return a.d>b.d;
}
priority_queue<Node>Heap;
int main(){
// freopen("j.in","r",stdin);
memset(d,0x7f,sizeof(d));
pw[0]=1;
for(int i=1;i<=8;++i){
pw[i]=pw[i-1]*8;
}
while(scanf("%s%d%s",s1,&pp,s2)!=EOF){
memset(cant,0,sizeof(cant));
bool flag=1;
while(!Heap.empty()){
Heap.pop();
}
En=0;
int U=0,len1=strlen(s1),len2=strlen(s2);
for(int i=0;i<len2;++i){
if(cant[s2[i]-'a'+1]){
flag=0;
break;
}
cant[s2[i]-'a'+1]=1;
}
if(!flag){
puts("-1");
continue;
}
for(int i=0;i<len1;++i){
U=U*8+s1[i]-'a'+1;
}
U=U*8+pp;
int goal=0;
for(int i=0;i<len2;++i){
goal=goal*8+s2[i]-'a'+1;
}
Heap.push(Node(U,0));
d[U]=0;
st[++En]=U;
while(!Heap.empty()){
Node now=Heap.top(); Heap.pop();
if(!vis[now.u]){
if(now.u/8==goal){
break;
}
vis[now.u]=1;
int U=now.u;
int len=0;
int gbp=U%8; U/=8;
memset(cant,0,sizeof(cant));
// char S[10];
while(U){
cant[U%8]=1;
// S[len++]=U%8+'a'-1;
++len;
U/=8;
}
// for(int i=0;i<len;++i){
// putchar(S[i]);
// }
// puts("");
//plus
if(len<7){
U=now.u;
U-=(U%pw[len-gbp+1]);
U*=8;
U+=(now.u%pw[len-gbp+1]);
for(int i=1;i<=7;++i){
if(!cant[i]){
int tU=U+i*pw[len-gbp+1];
++tU;
if(d[tU]>d[now.u]+2){
d[tU]=d[now.u]+2;
Heap.push(Node(tU,d[tU]));
st[++En]=tU;
}
}
}
}
//delete
if(len>0){
if(gbp>0){
U=now.u%pw[len-gbp+1];
int tmp=now.u;
tmp/=pw[len-gbp+2];
tmp*=pw[len-gbp+1];
U+=tmp;
--U;
if(d[U]>d[now.u]+2){
d[U]=d[now.u]+2;
Heap.push(Node(U,d[U]));
st[++En]=U;
}
}
if(gbp<len){
U=now.u%pw[len-gbp];
int tmp=now.u;
tmp/=pw[len-gbp+1];
tmp*=pw[len-gbp];
U+=tmp;
if(d[U]>d[now.u]+2){
d[U]=d[now.u]+2;
Heap.push(Node(U,d[U]));
st[++En]=U;
}
}
}
//move
if(gbp>0){
if(d[now.u-1]>d[now.u]+1){
d[now.u-1]=d[now.u]+1;
Heap.push(Node(now.u-1,d[now.u-1]));
st[++En]=now.u-1;
}
}
if(gbp<len){
if(d[now.u+1]>d[now.u]+1){
d[now.u+1]=d[now.u]+1;
Heap.push(Node(now.u+1,d[now.u+1]));
st[++En]=now.u+1;
}
}
}
}
printf("%.1f\n",(double)(*min_element(d+goal*8,d+goal*8+8))*0.5);
for(int i=1;i<=En;++i){
d[st[i]]=2000000000;
vis[st[i]]=0;
}
}
return 0;
}

【最短路】【Heap-dijkstra】hihocoder 1587 ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 J. Typist's Problem的更多相关文章

  1. hihoCoder 1582 Territorial Dispute 【凸包】(ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)

    #1582 : Territorial Dispute 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 In 2333, the C++ Empire and the Ja ...

  2. hihoCoder 1584 Bounce 【数学规律】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)

    #1584 : Bounce 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 For Argo, it is very interesting watching a cir ...

  3. hihoCoder 1578 Visiting Peking University 【贪心】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)

    #1578 : Visiting Peking University 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 Ming is going to travel for ...

  4. hihoCoder 1586 Minimum 【线段树】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)

    #1586 : Minimum 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 You are given a list of integers a0, a1, …, a2 ...

  5. hihocoder 1586 ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛-题目9 : Minimum【线段树】

    https://hihocoder.com/problemset/problem/1586 线段树操作,原来题并不难..... 当时忽略了一个重要问题,就是ax*ay要最小时,x.y可以相等,那就简单 ...

  6. 【分类讨论】【计算几何】【凸包】hihocoder 1582 ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 E. Territorial Dispute

    题意:平面上n个点,问你是否存在一种黑白染色方案,使得对于该方案,无法使用一条直线使得黑色点划分在直线一侧,白色点划分在另一侧.如果存在,输出一种方案. 如果n<=2,显然不存在. 如果所有点共 ...

  7. 【线段树】hihocoder 1586 ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 I. Minimum

    题意:给你一个序列(长度不超过2^17),支持两种操作:单点修改:询问区间中最小的ai*aj是多少(i可以等于j). 只需要线段树维护区间最小值和最大值,如果最小值大于等于0,那答案就是minv*mi ...

  8. hihoCoder #1586 : Minimum-结构体版线段树(单点更新+区间最值求区间两数最小乘积) (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)

    #1586 : Minimum Time Limit:1000ms Case Time Limit:1000ms Memory Limit:256MB Description You are give ...

  9. hihoCoder 1389 Sewage Treatment 【二分+网络流+优化】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛)

    #1389 : Sewage Treatment 时间限制:2000ms 单点时限:2000ms 内存限制:256MB 描述 After years of suffering, people coul ...

随机推荐

  1. IT培训班123

    最近20年,IT行业一直处于上升期,程序员的工资越来越高了,年薪几十万的程序员大有人在.根据国家统计局发布的2016年各行业平均工资报表,程序员已经是工资最高的一个群体,超过了金融行业. IT行业的火 ...

  2. Machine Learning(CF940F+带修改莫队)

    题目链接:http://codeforces.com/problemset/problem/940/F 题目: 题意:求次数的mex,mex的含义为某个集合(如{1,2,4,5})第一个为出现的非负数 ...

  3. Python中的异常处理 -- (转)

    python中的异常   异常是指程序中的例外,违例情况.异常机制是指程序出现错误后,程序的处理方法.当出现错误后,程序的执行流程发生改变,程序的控制权转移到异常处理. Exception类是常用的异 ...

  4. 分布式实时日志分析解决方案ELK部署架构

    一.概述 ELK 已经成为目前最流行的集中式日志解决方案,它主要是由Beats.Logstash.Elasticsearch.Kibana等组件组成,来共同完成实时日志的收集,存储,展示等一站式的解决 ...

  5. rtems-os-source

    http://blog.csdn.net/xpx3216/article/details/5776941 http://tech.hqew.com/fangan_421204 https://gith ...

  6. SqlServer存储过程中使用事务,示例

    create proc pro_GetProTrans @GoodsId int, @Number int, @StockPrice money, @SupplierId int, @EmpId in ...

  7. C++中多线程与Singleton的那些事儿

    前言 前段时间在网上看到了个的面试题,大概意思是如何在不使用锁和C++11的情况下,用C++实现线程安全的Singleton. 看到这个题目后,第一个想法就是用Scott Meyer在<Effe ...

  8. [会装]Spark standalone 模式的安装

    1. 简介 以standalone模式安装spark集群bin运行demo. 2.环境和介质准备 2.1 下载spark介质,根据现有hadoop的版本选择下载,我目前的环境中的hadoop版本是2. ...

  9. 2.C 基础

    C 基础 原文地址:http://rypress.com/tutorials/objective-c/c-basics OC 可以说是C语言的一个超集,这样你可以无缝的和C语言结合编程也就是你可以这两 ...

  10. FineReport——插入行策略

    1.空值是默认的选项,即每次插入新行时,格子都是空白的. 2.原值即单元格中原有内容是什么,就复制到新增的格子中,一般适用于单元格是使用公式定义的, 在插入单元格时,公式会保留下来. 3.默认值即通过 ...