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

题意:给你一个串,仅含有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;
}
posted @ 2017-09-23 23:03  AutSky_JadeK  阅读(273)  评论(0编辑  收藏  举报
TVアニメ「Charlotte(シャーロット)」公式サイト TVアニメ「Charlotte(シャーロット)」公式サイト