题意:给你一个串,仅含有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;
}

最新文章

  1. 转载:《TypeScript 中文入门教程》 8、函数
  2. opencv6.1-imgproc图像处理模块之平滑与形态学操作
  3. 自动布局(Masonry)设置tabbar
  4. IOS开发常用技术网站
  5. PHP面向对象(OOP):PHP5接口技术(interface)
  6. ThinkPHP 类似Yii的Gii生成Model的功能。
  7. cocos项目导入其它源文件时加入依赖库时,头文件提示找不到文件夹中的文件
  8. 深入理解C指针之二:C内存管理
  9. 【转】python数据格式化之pprint
  10. Beautifulsoup4
  11. linux netlink通信机制
  12. 通过Hutool 调用远程API接口(POST/GET)
  13. 企业级iptables防火墙实战
  14. Git 安装和使用教程(转载)
  15. win7 64安装msyql
  16. PHP 支持 JQuery 的 JSONP 跨域访问
  17. jrebel热部署
  18. Xilinx vivado迅雷下载地址(所有版本)
  19. Set-cookie无效(失效)
  20. python super()函数详解

热门文章

  1. 01背包入门 dp
  2. HDU 1175 连连看 (深搜+剪枝)
  3. frp 使用入门
  4. 【Python学习】程序运行完发送邮件提醒
  5. vs 2015 插件 supercharger 破解方式
  6. GCC在C语言中内嵌汇编 asm __volatile__ 【转】
  7. python实战===老司机奇技淫巧系列之字符转换成图片
  8. 【LOJbeta round1】ZQC的手办
  9. ASPxTreeList的右键按钮事件
  10. [New learn]SDWebImage框架的基本使用