#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
struct zhi {
int dx, st;
};
bool visit[1000008];
queue<zhi>q;
zhi da;
int bfs(int x, int k, int t) {
q.push({x, 0});
visit[x] = 1;
while(!q.empty())
{
if(k == 1)
{
int abc = 0;
while(x > 1)
{
x -= t;
abc++;
}
return abc;
}
da = q.front();
q.pop();//printf("%d %d\n", da.dx, da.st);
if(da.dx <= 0)
continue;
if(da.dx == 1)
return da.st;
if(da.dx <= t + 1) {
q.push({1, da.st + 1});
continue;
}
if(da.dx % k == 0 && !visit[da.dx / k])
{
q.push({da.dx / k, da.st + 1});
visit[da.dx / k] = 1;
}
for(int i = t; i >= 1; i--)
{
if(!visit[da.dx - i])
{
q.push({da.dx - i, da.st + 1});
visit[da.dx - i] = 1;
}
else
break;
}
}
}
int main()
{
int T, x, k, t;
scanf("%d", &T);
while(T--) {
memset(visit, 0, sizeof(visit));
scanf("%d%d%d", &x, &k, &t);
printf("%d\n", bfs(x, k, t););
while(!q.empty())
q.pop();
}
return 0;
}
题意:给定三个整数x, k, t, x每次减i, (0 <= i <= t ),如果x%k==0, 那么x = x/k,输出使x变成1的最小的步数。
BFS搜索,x为1时停下,输出步数。将每次x可以进行的操作入队。
一开始犯了两个错误,一是没有标记访问过的数,重复访问导致入队的数太多MLE了;二是没将所有的x-i ( 0 <= x <= t )入队,漏掉了一些情况,WA了很多次,第二天还是蓝总想明白的。