GDCPC2021 1177:Jerry

J-Jerry

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(1q100000) ,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(1di100000),which represents the distance Jerry want to move forward
Output
For each query, print an integer to represent the minimum cost of rice.
 
Sample Input

2
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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花生ono

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值