【BFS】【枚举】HihoCoder - 1251 - The 2015 ACM-ICPC Asia Beijing Regional Contest - C - Today Is a Rainy Day

时间:2021-03-13 04:24:55

题意:给你两个只由1~6组成的串,问你B串至少要经过几次操作变成A串。

一次操作要么选择一个种类的数,将其全部变成另一种类;要么选择一个数,将其变为另一个数。

可以证明,一定先进行一定数量的第一种操作,然后再进行一定数量的第二种操作。

所以可以BFS预处理序列每种数要变成哪种数所需要的代价。初始状态是123456,代表1->1,2->2,...,6->6,一共才6^6种状态。

然后再枚举一遍所有状态,把该种状态下,剩下的仍然不符的数强行变过去就行了,然后在所有答案中取个最小的。

#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
int d[700000];
bool vis[700000];
int n,pw[10];
queue<int>q;
char s[125],s2[125];
int main(){
//	freopen("c.in","r",stdin);
	memset(d,0x7f,sizeof(d));
	pw[0]=1;
	for(int i=1;i<=6;++i){
		pw[i]=pw[i-1]*10;
	}
	q.push(123456);
	vis[123456]=1;
	d[123456]=0;
	int t[7];
	while(!q.empty()){
		bool used[7]={0};
		int U=q.front(); q.pop();
		for(int i=1;i<=6;++i){
			if(!used[i]){
				int e=0;
				int wei=U/pw[i-1]%10;
				for(int j=i;j<=6;++j){
					if(wei==U/pw[j-1]%10){
						used[j]=1;
						t[++e]=j;
					}
				}
				for(int j=1;j<=6;++j){
					if(j!=wei){
						int tmp=U;
						for(int k=1;k<=e;++k){
							tmp+=(j-wei)*pw[t[k]-1];
						}
						if(!vis[tmp]){
							vis[tmp]=1;
							d[tmp]=d[U]+1;
							q.push(tmp);
						}
					}
				}
			}
		}
	}
	while(scanf("%s%s",s2+1,s+1)!=EOF){
		int ans=2147483647;
		n=strlen(s+1);
		for(int i=1;i<=6;++i){
			for(int j=1;j<=6;++j){
				for(int k=1;k<=6;++k){
					for(int l=1;l<=6;++l){
						for(int p=1;p<=6;++p){
							for(int q=1;q<=6;++q){
								int x=i*100000+j*10000+k*1000+l*100+p*10+q;
								if(d[x]<2000000000){
									int cnt=0;
									for(int pp=1;pp<=n;++pp){
										int tt;
										if(s[pp]=='1'){
											tt=i;
										}
										else if(s[pp]=='2'){
											tt=j;
										}
										else if(s[pp]=='3'){
											tt=k;
										}
										else if(s[pp]=='4'){
											tt=l;
										}
										else if(s[pp]=='5'){
											tt=p;
										}
										else{
											tt=q;
										}
										if(tt+'0'!=s2[pp]){
											++cnt;
										}
									}
									ans=min(ans,cnt+d[x]);
								}
							}
						}
					}
				}
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}