A、打靶
跳转原题点击此:A题地址
1、题目大意
小蓝在玩打靶游戏,每打到一个靶子得1分,当前一共n个靶子,还剩m个靶子没打,并且小蓝当前的分数是x,问当全部打完后分数是否有可能为y分。
2、题目解析
注意,小蓝有可能分数为空和当前分数大于y分。所以只要当前分数大于y分或者剩余的靶子不足以支撑其分数达到y分,否则就有可能达到y分。
#include<bits/stdc++.h>
using namespace std;
int t;
int n, m, x, y;
void solve()
{
cin >> n >> m >> x >> y;
int tmp1 = n - m;
int tmp2 = y - x;
// 如果当前分数大于y分或者剩余的靶子不足以支撑其分数达到y分
// 则输出No
if(tmp1 < tmp2 || x > y)
cout << "No" << endl;
else
cout << "Yes" << endl;
}
int main()
{
cin >> t;
while (t--)
{
solve();
}
return 0;
}
B、打靶
跳转原题点击此:B题地址
1、题目大意
给定gcd(a, b) 和 lcm(a, b)这两个数,要你求出符合gcd和lcm的a和b,如果有多个答案队,则输出a最小的答案队;如果a相等,则输出a最小同时b最小的答案对。如果无法求出a、b,则输出-1。
2、题目解析
数学知识:gcd(a, b) * lcm(a, b) == a * b; 同时因为a是最小的,则a只可能是gcd(a, b),因为最大公约数的最小值就是其本身 ,所以根据前面的数学知识,b就为lcm(a, b)。如果给定的gcd不是lcm的因子,则无法得到答案,输出-1:因为gcd是a和b的因子,而a和b又是lcm的因子,所以gcd是lcm的因子。
#include<bits/stdc++.h>
using namespace std;
int t;
int x, y;
void solve()
{
cin >> x >> y;
if(y % x != 0)
{
cout << -1 << endl;
return;
}
cout << x << " " << y << endl;
}
int main()
{
cin >> t;
while (t--)
{
solve();
}
return 0;
}
C、K级数列
跳转原题点击此:C题地址
1、题目大意
给定一个序列a和k值,询问是否存在一个数列b,使得\(|a_i - b_i| \le k\),其中\(i 为 [1,n]\),并且b数组为非递减数组。
2、题目解析
因为\(|a_i - b_i| \le k\),所以\(b_i\)的取值范围就是\([a_i - k, a_i + k]\),因为要满足b数组是非递减,所以贪心要尽可能选择b数组满足条件的同时尽可能小。
又因为只要a数组后一个数比前一个数大,就一定有答案,否则前面的数也无解。
所以,如果a数字当前的数的取值范围\(a_i + k\)比前一个数的最小选择范围还要小,则无解。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+10;
int t;
int n, k;
int f[N], l[N], r[N];
void solve()
{
cin >> n >> k;
for(int i = 1; i <= n; i++)
{
cin >> f[i];
// 找出a数组每个数的范围,存入l和r数组中
l[i] = f[i] - k;
r[i] = f[i] + k;
}
int tmp = l[1];
for(int i = 2; i <= n; i++)
{
// 如果后一个数的范围大于等于前一个数的最小范围,则肯定有解
// 此时,贪心选择能满足条件(b非递减)的数,
if(r[i] >= tmp)
tmp = max(tmp, l[i]);
// 否则无解
else
{
cout<<"No\n";
return;
}
}
cout<<"Yes\n";
}
int main()
{
cin >> t;
while (t--)
{
solve();
}
return 0;
}