A - Plus One on the Subset
直接求极差即可
#include <bits/stdc++.h>
#define int long long
using namespace std;
inline void solve(){
int n = 0; cin >> n;
int maxx = -1, minn = INT_MAX;
for(int i = 1; i <= n; i++){
int x = 0; cin >> x;
maxx = max(maxx, x), minn = min(minn, x);
}
cout << maxx - minn << endl;
}
signed main(){
int t = 0; cin >> t;
while(t--) solve();
return 0;
}
B - Make AP
等差数列性质题,分三种情况( { m ∗ a , b , c } { a , m ∗ b , c } { a , b , m ∗ c } \{m*a, b, c\}\{a, m*b, c\}\{a, b, m*c\} {m∗a,b,c}{a,m∗b,c}{a,b,m∗c})讨论即可
#include <bits/stdc++.h>
using namespace std;
inline void solve(){
int a, b, c; cin >> a >> b >> c;
if(a == b == c || b - a == c - b || a - b == b - c){ cout << "YES" << endl; return; }
double d = 2.0 * b - c;
if((int)d % a == 0 && d >= a && (int)d == d){ cout << "YES" << endl; return; }
d = 2.0 * b - a;
if((int)d % c == 0 && d >= c && (int)d == d){ cout << "YES" << endl; return; }
d = (a + c) / 2.0;
if((int)d % b == 0 && d >= b && (int)d == d){ cout << "YES" << endl; return; }
cout << "NO" << endl;
}
signed main(){
int t = 0; cin >> t;
while(t--) solve();
return 0;
}
C - Division by Two and Permutation
题目大意
给定一个长度为 n n n的序列,每次操作可以对某个元素除以2向下取整。问能否通过有限次操作使序列变为数字 [ 1 , n ] [1,n] [1,n]的一个排列
思路
首先再读入的时候进行一次处理:因为构成 1 − n 1-n 1−n排列的数字必不可能大于 n n n,因此将大于 n n n的数字除到小于 n n n。
然后对每个元素的数值进行标记,如果某个数字存在的次数超过了两次,那么就对该数字不停的操作直到某一次操作后的数字不存在于当前的序列中,对该操作后的数字进行标记。如果不停的操作之后数字变为
0
0
0,那么说明该数字无法通过除二操作变为某个不存在的数字,此时直接输出NO
即可
Accepted Code
#include <bits/stdc++.h>
using namespace std;
const int N = 100;
int a[N], book[N];
inline void solve(){
int n = 0; cin >> n;
memset(book, 0, sizeof(book));
for(int i = 1; i <= n; i++){
cin >> a[i];
while(a[i] > n) a[i] >>= 1;
book[a[i]]++;
}
for(int i = 1; i <= n; i++){
while(book[a[i]] >= 2){
int num = a[i] >> 1;
while(book[num] && num) num >>= 1;
if(!num){ cout << "NO" << endl; return; }
else book[a[i]]--, book[num]++;
}
}
cout << "YES" << endl;
}
signed main(){
int t = 0; cin >> t;
while(t--) solve();
return 0;
}
D - Palindromes Coloring
题目大意
给一个字符串涂色,共有 k k k个颜色,每个颜色都至少涂到一个字符上去,但是字符串可以不涂完。相同颜色字符可以任意交换。
然后相同颜色的字符放在一起构成一堆回文串,使最短的回文串尽可能地。求最短回文串的长度
思路
相同颜色字符可以任意交换,那么跟顺序的关系就不大了。所以直接统计落单的字符个数和成对的字符对数。
用成对的字符数量除以颜色数量可以得到基础长度,如果落单的字符个数加上多余组数的大于 k k k,那么需要在基础长度上 + 1 +1 +1。
Accepted Code
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int book[30];
inline void solve(){
int n, k; cin >> n >> k;
memset(book, 0, sizeof book);
for(int i = 1; i <= n; i++){
char x; cin >> x;
book[x - 'a' + 1]++;
}
if(n == k){ cout << 1 << endl; return; }
int cnt = 0;
for(int i = 1; i <= 26; i++)
if(book[i] & 1) cnt++;
int num = (n - cnt) >> 1, ans = (num / k) << 1;
if((num % k) * 2 + cnt >= k) ans += 1;
cout << ans << endl;
}
signed main(){
int t = 0; cin >> t;
while(t--) solve();
return 0;
}