【C++/贪心】小贪一手(CCSU_ACM 21新生赛)

196 阅读1分钟

题目描述

给定整数 n,x,y ,求 [0,n] 范围内的最大整数 k ,使得 k 满足 k%x=y 。

输入描述:

第一行一个正整数 t ,表示有 t 组数据
接下来 t 行,每行三个整数x,y,n 
1≤t≤5×10^4
2≤x≤10^9
0≤y<x
y≤n≤10^9

输出描述:

对于每个测试案例,打印答案——最大的非负整数 k ,使 0≤k≤n 且 k mod x=y 。可以保证答案总是存在的。

输入

7
7 5 12345
5 0 4
10 5 15
17 8 54321
499999993 9 1000000000
10 5 187
2 0 999999999

输出

12339
0
15
54306
999999995
185
999999998

思路

第一种思路:暴力枚举

//暴力枚举,还浅浅的优化了一下下,依然超时
#include <bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin>>t;
    vector<int> x(t),y(t),n(t);
    for(int i=0;i<t;i++)
    {
        cin>>x[i]>>y[i]>>n[i];
        for(int j=n[i];j>=0;j--)
        {
            if(j%x[i]==y[i])
            {
                cout<<j<<endl;
                break;
            }
        }
    }
    
    return 0;
}

很明显暴力枚举不行,那么就来思考怎么更大的优化,要使得k%x==y,可以知道n[i]/x[i]是n[i]里最多能有多少个x[i],再通过 上述表达式*x[i]+y[i]可以算出 TMP ,这个TMP的值的特点是 TMP % x[i]==y[i] 但是这个值要比n[i]大,所以我循环减去x[i],TMP的值依然%x[i]==y[i],直到TMP的值小于或者等于n[i]就可以输出了。

AC代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin>>t;
    vector<long long> x(t),y(t),n(t);
    
    
    for(int i=0;i<t;i++)
    {
        
        cin>>x[i]>>y[i]>>n[i];
        long long int m=n[i]/x[i];
        long long int tmp=m*x[i]+y[i];
        for(long long int j=tmp;j>=0;j-=x[i])
        {
            if(j<=n[i])
            {
                cout<<j<<endl;
                break;
            }
                
        }
    }
    
    return 0;
}

//2022.5.10 CCSU_ACM 21新生赛