A. Elections
有三个候选人,每个候选人都有一个初始票数,问每个候选人至少增加多少票才能绝对被选上。
判断其中一个的初始票数是否大于另外两个的最大值,如果大于,那这个人就不需要增加选票,否则需要增加选票直至刚好超过最大值。
A
#include
#include
using namespace std;
int main() {
int t; cin >> t;
while (t--) {
int a, b, c; cin >> a >> b >> c;
cout << (a > max(b, c) ? 0 : max(b, c) - a + 1)<<" ";
cout << (b > max(a, c) ? 0 : max(a, c) - b + 1)<<" ";
cout << (c > max(a, b) ? 0 : max(a, b) - c + 1) << endl;
}
}
B. Make it Divisible by 25
给定一个数,每次可以删除一位,例如 3995删除第一位变成995,20065删除第一位变成65,显然去掉前导零。求最少多少次删除后,可以使得得到的数可以被25整除。
我们不难发现,如果最后两位没办法整除25的话,那么最后的数,无论如何都不能整除25,也就是说,应该要先修改结尾的两位数,如果最后两位不对的话,前面修改再多都是没有用的。所以我们大可不必考虑前导零的问题,就只对最后两位进行删除就可以了,这个过程可以用bfs来实现。
当然这里也不是说只要最后两位可以整除25,那么整个数就可以整除25,不要混淆。
#include
using namespace std;
typedef long long ll;
int bfs(ll n)
{
queue<pair<ll,int>> q;
q.push({n,0});
map<ll,int> mp;
while (!q.empty())
{
//记录数,记录步数
pair<ll,int> p = q.front();
q.pop();
if (p.first<25)continue;
if (p.first%25==0)return p.second;
pair<ll,int> pge = {p.first/10,p.second+1};
pair<ll,int> pshi = {p.first/100*10+p.first%10,p.second+1};
if (!mp[pge.first])
{
mp[pge.first]=1;
q.push(pge);
}
if (!mp[pshi.first])
{
mp[pshi.first]=1;
q.push(pshi);
}
}
}
int main()
{
int t;cin>>t;
while (t--)
{
ll n;cin>>n;
cout<<bfs(n)<<endl;
}
}
C. Save More Mice
有一条长长的走廊,一只猫在走廊的起始点,有一堆老鼠在走廊的任意地方分布(不包括0,n位置),老鼠洞口在n处,老鼠进洞以后,就安全了,猫可以把它所在位置的老鼠全都吃掉。每次可以将一只老鼠向右移动一格,同时猫也会向右移动一格。求最终最多可以存活几只老鼠。
简单贪心问题,老鼠一定是离洞口近的先跑,因为如果最远的先跑,那么最终的结局就是,猫离本来可以跑掉的老鼠越来越近,反而跑不掉了,所以能跑的一定先跑。
猫最远到达的位置是n-1,因为猫到洞口是不会吃老鼠的。
综上,就升序排序后反着枚举就ok
#include
#include
using namespace std;
const int M = 4e5 + 100;
int a[M];
int main() {
int t; cin >> t;
while (t--) {
int n, k; cin>>n>>k;
for (int i = 1; i <= k; i++) {
cin >> a[i];
}
sort(a + 1, a + 1 + k);
int ans = 0; int step = n - 1;
for (int i = k; i >= 1; i--) {
if (step - (n - a[i]) >= 0) {
ans++; step -= n - a[i];
}
else
break;
}
cout << ans << endl;
}
return 0;
}
D1. All are Same
给定一个数组,可以对任意一个元素减k,求最大k为多少可以使得最终数组全部元素相同。
因为是每次减,所以最后数组元素相同,所以最终元素一定是最小元素,所以就找出每个元素和最小元素的差值,然后求他们的最大公因数就欧克了。
#include
#include
#include
using namespace std;
const int M = 45;
int a[M];
int cha[M];
inline int gcd(int a, int b) {
int r;
while (b > 0) {
r = a % b;
a = b;
b = r;
}
return a;
}
int main() {
int t; cin >> t;
while (t--) {
map<int, int> mp;
int n; cin >> n; int minn = 1e9; int maxn = -1e9;
for (int i = 1; i <= n; i++) {
cin >> a[i];
minn = min(minn, a[i]);
maxn = max(maxn, a[i]);
}
int tot = 0;
//cout << minn << endl;
for (int i = 1; i <= n; i++) {
if (a[i] != minn) {
int ca = a[i] - minn;
if (!mp.count(ca)) {
mp[ca]++;
cha[++tot] = ca;
}
}
}
int g = 0;
// for (int i = 1; i <= tot; i++) cout << cha[i] << " ";
//cout << endl;
for (int i = 1; i <= tot; i++) {
g = gcd(g, cha[i]);
}
cout << g << endl;
}
}
D2. Half of Same
给定一个数组,可以对任意一个数减k,求最大k为多少可以使得最终数组元素至少一半相同。
这个题相较于D1复杂一些,但是思路大同小异,需要求出每个元素的差值与差值之间的最大购买后因数,然后枚举这些最大公因数,并判断有多少元素之间差值是枚举数的倍数,当元素差值数量大于n/2时就是一种情况,每次取max。
#include
#include
#include
#include
using namespace std;
int a[50];
bool cmp(int a, int b) {
return a > b;
}
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
int main() {
int t; cin >> t;
while (t--) {
map<int, int> mp;
int n; cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
mp[a[i]]++;
}
int f = 0;
for (auto it : mp) {
if (it.second >= n / 2) {
cout << "-1" << endl;
f = 1;
break;
}
}
if (f == 1)continue;
set<int> s;
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
int cha = abs(a[i] - a[j]);
s.insert(cha);
}
}
set<int> p;
for (auto f1 : s) {
for (auto f2 : s) {
int g = gcd(f1, f2);
p.insert(g);
}
}
int ans = -1e9;
for (auto tp : p) {
if (!tp) continue;
for (int i = 1; i <= n; i++) {
int tmp = 0;
for (int j = 1; j <= n; j++) {
int cha = abs(a[i] - a[j]);
if (cha % tp == 0) {
++tmp;
}
if (tmp >= n / 2) ans = max(ans, tp);
}
}
}
cout << ans << endl;
}
}
持续更新ing~