这几天做的北京的模拟,当时被这个题给卡住了,自己写的BFS,一直WA,结束后对拍才找到自己的致命错误
自己做的时候直接通过最优情况去推导最有情况,导致自己掉进死胡同了
这里举一个例子,比如变成01034
依次是,12345,12354,12534,12034,21034,31034,41034,51034,01034
可以见到这里的51034用了7步,而实际上51034最优策略是6步,这里为什么用7步的51034,而不用6步的51034呢?
是因为变成7步的51034,用了一次乘法,三次加法,变成6布的51034,用了两次乘法,三次加法,而变成01034,
需要一步乘法,可是6步的51034不能再使用乘法了
所以这个约束条件就导致了不能用最优的低步数答案去推到最优的高步数答案
这里的解决方法应该是把用了三次加法,一次乘法的51034和用了三次加法,两次乘法的51034分别记录下来
这里开一个数组ans[num][ins][dou],分别代表这个数,加法次数,乘法(乘二)次数
祈福 FREE LOOP 西安获得奖牌,加油!!!
附上改过之后AC的代码
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 100000 + 10;
const int INF = 0x3f3f3f3f;
struct mynum
{
int num;
int tt;
};
struct sta
{
string str;
int time;
int dou;
int ins;
};
int ans[maxn][5][5];///[number][ins][dou]
void bfs(string str1, int time1, int dou1, int ins1)
{
queue<sta> q;
q.push(sta{str1, time1, dou1,ins1});
while(!q.empty())
{
sta top = q.front();
q.pop();
int n = 0;
int ten = 1;
for(int i = 4; i >= 0; i--)
{
n += (int)(top.str[i] - '0') * ten;
ten = ten * 10;
}
if(ans[n][top.ins][top.dou] <= top.time)
continue;
ans[n][top.ins][top.dou] = min(ans[n][top.ins][top.dou], top.time);
/// printf("n : %d : time : %d\n" ,n ,top.time);
if(top.dou >= 1)///乘二
{
string tmp = top.str;
for(int i = 0; i < 5; i++)
{
int a = (int)(top.str[i] - '0');
if(a == 0)
continue;
a = (a * 2) % 10;
top.str[i] = a + '0';
q.push(sta{top.str, top.time+1, top.dou-1, top.ins});
top.str = tmp;
}
}
for(int i = 0 ; i < 4; i++)///相邻交换
{
char c;
string tmp = top.str;
/// cout<<top.str<<" ";
c = top.str[i];
if(top.str[i] == top.str[i+1])
continue;
top.str[i] = top.str[i+1];
top.str[i+1] = c;
/// cout<<top.str<<endl;
q.push(sta{top.str, top.time + 1, top.dou, top.ins});
top.str =tmp;
}
if(top.ins >= 1)///自增加一
{
string tmp = top.str;
for(int i = 0; i < 5; i++)
{
int a = (int)(top.str[i] - '0');
a = (a + 1)% 10;
top.str[i] = a + '0';
/// cout<<str<<endl;
q.push(sta{top.str, top.time+1, top.dou, top.ins-1});
top.str = tmp;
}
}
}
}
int main()
{
/// freopen("2.out","w",stdout);
memset(ans, INF, sizeof(ans));
string sss = "12345";
bfs(sss, 0, 2, 3);
string myans;
/// cout<< " total:" << cnt <<endl;
/// for(int i = 0; i <cnt; i++) printf("%d %d\n", a[i].num, a[i].tt);
while(cin>>myans)
{
int n = 0;
int ten = 1;
//myans.length()-1
for(int i = myans.length()-1; i >= 0; i--)
{
n += (int)(myans[i] - '0') * ten;
ten = ten * 10;
}
int freeloop = INF;
for(int i = 0; i <= 3; i++)
{
for(int j = 0; j <= 2; j++)
{
freeloop = min(freeloop, ans[n][i][j]);
}
}
if(freeloop == INF)
{
printf("-1\n");
}
else
{
printf("%d\n", freeloop);
}
/// n++;
}
return 0;
}