| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
共有 1141 人关注过本帖
标题:这道题请大家帮忙看一下,谢谢!
只看楼主 加入收藏
yywx2023
Rank: 1
来 自:江苏
等 级:新手上路
帖 子:20
专家分:4
注 册:2025-4-30
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:5 
这道题请大家帮忙看一下,谢谢!
如果一个数满足它是 X
 的倍数,但是不是 100×X
 的倍数,就说它是一个 X数。

有 T次询问,每次询问会给定一个整数 X,请问不小于 a的第 b小的 X数是多少?

输入格式
第一行一个整数 T
,表示询问次数。

接下来 T行,每行包含三个整数 X,a,b


输出格式
输出共 T行,每行包含一个整数表示当前询问的答案。

样例输入
3
10 1000 1
2 -10 2
1 100 10000
样例输出
1010
-8
10201

样例解释
当 X=10,a=1000时,不小于 1000的 X数从小到大依次是 1010,1020,...,所以第 1小的 X 数是 1010


当 X=2,a=−10时,不小于 −10的 X数从小到大依次是 −10,−8,..,所以第 2小的 X数是 −8。

数据范围
对于 20%的数据,保证 1≤b≤10

对于另外 30% 的数据,保证 1≤a,b≤1000

对于 100%的数据,保证 1≤T≤105,1≤X≤100,|a|≤109,1≤b≤109



本人知识储备还没有大家多,望大家多多关照,希望不要用过于高深的代码来解这道题,谢谢!

[此贴子已经被作者于2025-4-30 12:14编辑过]

搜索更多相关主题的帖子: 询问 输出 数据 小于 整数 
2025-04-30 11:57
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9051
专家分:54255
注 册:2011-1-18
收藏
得分:20 
1)“第一个大于等于a,且是X的倍数”的数是 (a/X)向上取整,然后乘以x
 “第一个大于等于a,且是X的倍数,且不是100X倍数”的数是 (a/X)向上取整,如果它是100的倍数的话,再加一,然后乘以X

2)设第一个【X数】是1*X,那么Y是第几个【X数】?
 答:因为每连续的100个【X的倍数】要被舍弃掉一个100X的倍数,所以Y是第 Y/X - Y/X/100 个【X数】
   例如 1X 是第 1 个【X数】
   例如 99X 是第 99 个【X数】
   例如 101X 是第 100 个【X数】
 错误的是,按上面的公式求得 -1X 是第 -1 个【X数】,这就不对了,既然设 1X 是第一个【X数】,那么 -1X 就应该是第0个【X数】。也就是负数的话,需要增加1。

3)求第n个【X数】是多少?也就是求2)的反函数
 解:设结果是 (100p+q)X,其中 0<q<100
   那么按照2)的结论有 (100p+q) - (100p+q)/100 = n,化简得 (n-q)/99 = p
   例如求第100个【X数】,因为 (100-1)/99=1,即p=1,1=1,结果是 (1*100+1)X = 101X
   例如求第99个【X数】,因为 (99-99)/99=1,即p=0,q=99,结果是 (0*100+99)X = 99X
   例如求第0个【X数】,因为 (0-99)/99=-1,即p=-1,q=99,结果是 (-1*100+99)X = -X
   例如求第-1个【X数】,因为 (-1-98)/99=-1,即p=-1,q=98,结果是 (-1*100+98)X = -2X

程序代码:
#include <iostream>
using namespace std;

int main( void )
{
    size_t T;
    cin >> T;
    while( T-- )
    {
        int x, a, b;
        cin >> x >> a >> b;

        // 求【第一个大于a的【x数】】是x的几倍
        int t = (a>=0)
            ? (a+x-1)/x + ((a+x-1)/x%100==0)
            : a/x + (a/x%100==0);

        // 求 tx 是第几个【x数】
        int m = t - t/100;
        m += m<0;
       

        // 求第 n 个【x数】是多少
        int n = m + (b-1);
        int q = n%99==0 ? 99 : (n%99+99)%99;
        int p = (n-q)/99;
        int result = (p*100 + q)*x;
        cout << result << '\n';
    }
}

2025-04-30 20:29
yywx2023
Rank: 1
来 自:江苏
等 级:新手上路
帖 子:20
专家分:4
注 册:2025-4-30
收藏
得分:0 
回复 2楼 rjsp
谢谢!十分感谢您的指导,谢谢!
2025-05-01 15:54
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9051
专家分:54255
注 册:2011-1-18
收藏
得分:0 
上面是“设第一个【X数】是1*X,”,假如改为“设第0个【X数】是1*X,”的话,且放宽到允许用浮点数

程序代码:
#include <iostream>
#include <cmath>
using namespace std;

int main( void )
{
    size_t T;
    cin >> T;
    while( T-- )
    {
        int x, a, b;
        cin >> x >> a >> b;

        // 求【第一个大于a的【x数】】是x的几倍
        // a/x 向上取整,若为100的倍数,再增一
        int t = (int)ceil(a*1.0/x);
        if( t%100 == 0 )
            t += 1;

        // 求 tx 是第几个【x数】
        // t*99/100 向下取整
        int m = (int)floor( 99/100.0 * t );

        // 求第 n 个【x数】是多少
        // t*100/99 向下取整,再增一
        int n = m + (b-1);
        int result = 1 + (int)floor( 100/99.0 * n );
        cout << result*x << '\n';
    }
}

2025-05-02 11:12
XXGGZZQQ
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2024-8-12
收藏
得分:0 
一下是二分答案的程序(配有详细注释,写的比较匆忙,可能有误)
```
#include <bits/stdc++.h>
using namespace std;
typedef long long LL; // 使用LL代替long long,方便书写

int main()
{
    int T; // 询问次数
    scanf("%d", &T);
    while (T--) // 处理每个询问
    {
        int X, a, b;
        scanf("%d%d%d", &X, &a, &b); // 读入X, a, b
        
        // 计算起始的k值,满足k*X >= a
        LL start_k;
        if (a % X == 0)
        {
            start_k = a / X; // 如果a是X的倍数,直接取商
        }
        else
        {
            // 如果a是正数且不是X的倍数,需要向上取整
            if (a > 0)
            {
                start_k = a / X + 1;
            }
            else
            {
                // 如果a是负数,除法会自动向下取整,结果已经是满足k*X >= a的最小值
                start_k = a / X;
            }
        }
        
        // 调整start_k,确保不是100的倍数(因为100倍数的数不算X数)
        LL adj_k = start_k; // adj_k表示调整后的起始k值
        if (adj_k % 100 == 0)
        {
            adj_k++; // 如果起始k是100的倍数,跳过它
        }
        
        // 二分查找:寻找第b个有效的k值(即不是100的倍数)
        LL left = adj_k;   // 左边界
        LL right = adj_k + 1LL * b * 100; // 右边界(足够大)
        while (left < right)
        {
            LL mid = (left + right) / 2; // 中间值
            
            // 计算[left, mid]区间内的有效k的数量
            // 总共有 (mid - adj_k + 1) 个数
            // 减去其中是100的倍数的数的个数
            LL total = mid - adj_k + 1; // 区间内总共有多少个数
            LL invalid = (mid / 100) - ((adj_k - 1) / 100); // 区间内是100的倍数的数的个数
            LL cnt = total - invalid; // 有效数的数量
            
            if (cnt < b)
            {
                // 如果有效数不够,需要扩大右边界
                left = mid + 1;
            }
            else
            {
                // 否则缩小右边界
                right = mid;
            }
        }
        
        // 最终结果就是left对应的数(left是满足条件的第b小的k值)
        LL ans = left * X;
        printf("%lld\n", ans);
    }
}
5 天前 10:14
yywx2023
Rank: 1
来 自:江苏
等 级:新手上路
帖 子:20
专家分:4
注 册:2025-4-30
收藏
得分:0 
回复 5楼 XXGGZZQQ
谢谢!
5 天前 22:44
快速回复:这道题请大家帮忙看一下,谢谢!
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.036345 second(s), 10 queries.
Copyright©2004-2025, BC-CN.NET, All Rights Reserved