2015ACM/ICPC 北京賽區現場賽C 【bfs】
阿新 • • 發佈:2018-12-12
題意:
將字串2變成字串1,有兩種改變方法
1.將所有的同一字元換成另一種字元,只需要一步
2.將一個字母換成另一個字母,只需要一步
求出最少的改變次數
分析:
先bfs只進行第一種操作的所有可能方案,之後只進行2操作
程式碼:
#include<bits/stdc++.h> #define inf 0x3f3f3f3f using namespace std; const int maxn=120; int dp[800010]; char s1[maxn],s2[maxn]; int tmp[10],cnt,id[1000010],stp[1000010]; int a[maxn],c[maxn]; void bfs() { tmp[7]=cnt=1; for(int i=6;i>=1;i--) tmp[i]=tmp[i+1]*10; queue<int>q; q.push(123456); for(int i=0;i<=666666;i++) dp[i]=inf; dp[123456]=0; id[cnt]=123456; stp[cnt]=0; while(!q.empty()) { int x=q.front(); q.pop(); for(int i=1;i<=6;i++) for(int j=1;j<=6;j++) if(i!=j) { int xx=0; for(int k=1;k<=6;k++) { xx*=10; int l=(x%tmp[k])/tmp[k+1]; if(l==i) xx+=j; else xx+=l; } if(dp[x]+1<dp[xx]) { dp[xx]=dp[x]+1; id[++cnt]=xx; stp[cnt]=dp[xx]; q.push(xx); } } } } void solve() { int ans=inf,len=strlen(s1); for(int i=1;i<=cnt;i++) { for(int j=0;j<len;j++) a[j]=(s2[j]&15); for(int j=1;j<=6;j++) c[j]=(id[i]%tmp[j])/tmp[j+1]; for(int j=0;j<len;j++) a[j]=c[a[j]]; int sum=0; for(int j=0;j<len;j++) if(a[j]!=(s1[j]&15)) sum++; ans=min(ans,sum+stp[i]); } printf("%d\n",ans); } int main() { bfs(); while(scanf("%s%s",s1,s2)!=EOF) solve(); return 0; }