這幾天做的北京的模擬,當時被這個題給卡住了,自己寫的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;
}