本来以为是个DP,想这怎么转移,一直不会做,后来看了题解发现好简单
1.对于两种操作的这类问题,要想好操作的顺序会不会影响,这题而言,如果你是操作1和操作2间歇着做的话,一定不如把操作二都做完之后再对那些做过操作一的做一次操作
(想一想就知道了,当时也想找到操作之间的关系,可是没发现,好题啊!)
2. 考虑做完操作2之后的情况,同一种颜色一定会变成同一种颜色,所以状态数最多就6^6种,然后用BFS枚举出 123456到每种状态的最小步数
每次只要枚举每种做完操作2之后的情况,然后模拟操作一,就可以求出最优值了
1A
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
using namespace std;
const int INF = 1 << 30;
int step[1000000];
void init()
{
queue<int> q;
q.push(123456);
memset(step,-1,sizeof(step));
step[123456] = 0;
while(!q.empty()){
int p = q.front();
int x = p;
q.pop();
int a[10];
for(int i = 5; i >= 0; i--){
a[i] = x % 10;
x = x / 10;
}
for(int i = 1; i <= 6; i++)
for(int j = 1; j <= 6; j++){
int tmp1[7];
for(int k = 0; k <= 5; k++){
tmp1[k] = a[k];
}
for(int k = 0; k <= 5; k++){
if (a[k] == i){
a[k] = j;
}
}
/*for(int k = 0; k <= 5; k++){
printf("%d ",a[k]);
}
*/
int next = a[0];
for(int k = 1; k <= 5; k++){
next = next*10;
next = next + a[k];
}
// printf("%d\n",next);
if (step[next] == -1){
step[next] = step[p] + 1;
q.push(next);
}
for(int k = 0; k <= 5; k++)
a[k] = tmp1[k];
}
}
return;
}
int main()
{
//freopen("t.txt","w",stdout);
init();
char s1[200],s2[200];
while(scanf("%s%s",s2,s1) != EOF){
int l1 = strlen(s1);
int ans = INF;
int cur;
int i[7];
for(i[1] = 1; i[1] <= 6; i[1]++)
for(i[2] = 1; i[2] <= 6; i[2]++)
for(i[3] = 1; i[3] <= 6; i[3]++)
for(i[4] = 1; i[4] <= 6; i[4]++)
for(i[5] = 1; i[5] <= 6; i[5]++)
for(i[6] = 1; i[6] <= 6; i[6]++){
int next = i[1] * 100000 + i[2] * 10000 + i[3] * 1000 + i[4] * 100 + i[5] * 10 + i[6];
cur = step[next];
if (cur == -1) continue;
for(int j = 0; j < l1z; j++){
int a1 = s1[j] - '1' + 1;
int a2 = s2[j] - '1' + 1;
int a3 = i[a1];
if (i[s1[j] - '1' + 1] != (s2[j] - '1' + 1)) cur++;
}
//if (cur == 6) printf("%d\n",next);
ans = min(ans,cur);
}
printf("%d\n",ans);
}
return 0;
}