Description
Although Jerry is a mouse, he likes perfect square numbers. If a number can be expressed as the square of an integer, it is called perfect square numbers. Jerry can use magic to move forward or backward a distance of any perfect square numbers, which costs a grain of rice each time. And the position after each use of magic can not be behind the initial position or more than 1 0 5 10^5 105 distance in front of the initial position. Next, there are q questions, each time asking how much rice at least it takes for Jerry to move forward di .Note that each question is an independent one.
Input
The first line contains an integer q ( 1 ≤ q ≤ 100000 ) q(1 ≤ q ≤ 100000) q(1≤q≤100000) ,which represents the number of questions you need to solve.
Each of the next q q q lines contains an integer d i ( 1 ≤ d i ≤ 100000 ) d_i(1 ≤ d_i ≤ 100000) di(1≤di≤100000),which represents the distance Jerry want to move forward
Output
For each query, print an integer to represent the minimum cost of rice.
Sample Input2 8 7
Sample Output
2 2
Hint
In the first query: 0 -> 4 -> 8.
In the second query: 0 -> 16 -> 7;
解题思路:
从 0 到每一个完全平方数的步数都为 1 ,然后从每个完全平方数再向左右走一个完全平方数,步数为 2 ,后面也是如此……总之保存最小的那个步数。
代码1:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int d[N];
vector<int> step;
void BFS()
{
queue<int> q;
d[0] = 0;
q.push(0);
while(q.size())
{
int t = q.front();
q.pop();
for(auto i:step)
{
int l = t-i;
int r = t+i;
//向左走到之前不能走到的
if(l>=1 && !d[l])
{
d[l] = d[t]+1;
q.push(l);
}
//向右走到之前不能走到的
if(r<=N && !d[r])
{
d[r] = d[t]+1;
q.push(r);
}
}
}
}
void init()
{
//将完全平方数存起来作为移动步数
for(int i=1; i*i<=N; i++)
step.push_back(i*i);
BFS();
}
int main()
{
init();
int _ = 1;
cin>>_;
while(_--)
{
int a;
scanf("%d", &a);
printf("%d\n", d[a]);
}
return 0;
}
代码2:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int d[N];
void init()
{
memset(d, 0X3f, sizeof(d));
//走到每一个完全平方数的步数都为 1
for(int i=1;i*i<=100000;i++) d[i*i]=1;
//确定到每个数的最小步数
for(int i=1;i<=100000;i++)
{
//从每一个完全平方数到 i 的步数,若比原来小则覆盖步数
for(int l=1;l*l<=100000;l++)
{
if(i-l*l > 0) //完全平方数 l*l 往左走
d[i]=min(d[i],d[i-l*l]+1);
if(i+l*l <= 100000) //完全平方数 l*l 往右走
d[i]=min(d[i],d[i+l*l]+1);
}
}
}
int main()
{
init();
int _ = 1;
cin>>_;
while(_--)
{
int a;
scanf("%d", &a);
printf("%d\n", d[a]);
}
return 0;
}