传送门
A. 签到啦
排个序每次选最大的
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define fi first
#define se second
using namespace std;
const int N =100010;
int a[N],b[N];
int n, m;
void solve() {
cin >> n >> m;
for (int i = 0; i < n; i++)cin >> a[i];
sort(a, a + n, greater<int>());
int cnt = 0;
for (int i = 0; i < n; i++) {
cnt += a[i];
if (cnt >= m) {
cout << i + 1 << endl;
return;
}
}
}
int32_t main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int h_h;
cin >> h_h;
//h_h = 13;
while (h_h--)solve();
return 0;
}
Problem B. 熙巨打票
将操作实际和冷却时间打包,但是在两台机器打印最后一张的时候去除冷却时间即可,咬住以如果冷却时间小于打印时间要另外计算
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define fi first
#define se second
using namespace std;
const int N =100010;
int a[N],b[N];
int n, m;
void solve() {
int a, b, n;
cin >> a >> b >> n;
if (b >= a) {
cout << b * n << endl;
return;
}
if (n & 1) {
int x = n / 2;
cout << x * (a + b) + b << endl;
} else {
int x = n / 2 - 1;
cout << x * (a + b) + b + b << endl;
}
}
int32_t main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int h_h;
cin >> h_h;
//h_h = 13;
while (h_h--)solve();
return 0;
}
C. 三元分配
分情况讨论,要使两辆配对,则总和必须是偶数,又分为全是偶数和两个奇数和一个偶数,全是偶数一定可以两两配对,而如果有奇数的话,就需要偶数和其中的两个奇数的额和都是质数,还有两种特殊情况,偶数为零的话只能考虑另外两个奇数的和是不是质数,还有另外两个奇数唯一就肯定可以分配,赛时没考虑零的情况wa了很多发
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
bool vis[N];
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int T;
cin >> T;
vis[1] = 1;
for (int i = 2; i <= N; i++) {
if (!vis[i]) {
for (int j = i + i; j <= N; j += i) {
vis[j] = 1;
}
}
}
while (T--) {
int a, b, c;
cin >> a >> b >> c;
if ((a + b + c) % 2 != 0) cout << 'P' << '\n';
else {
if (a % 2 == 0 && b % 2 == 0 && c % 2 == 0)cout << 'R' << '\n';
else if (a % 2 == 0) {
if (a == 0) {
if (!vis[c + b])cout << 'R' << endl;
else cout << 'P' << '\n';
} else if (b + c == 2) cout << 'R' << '\n';
else if (!vis[a + b] && !vis[a + c])cout << 'R' << '\n';
else cout << 'P' << '\n';
} else if (b % 2 == 0) {
if (b == 0) {
if (!vis[a + c])cout << 'R' << endl;
else cout << 'P' << '\n';
} else if (a + c == 2) cout << 'R' << '\n';
else if (!vis[a + b] && !vis[b + c])cout << 'R' << '\n';
else cout << 'P' << '\n';
} else if (c % 2 == 0) {
if (c == 0) {
if (!vis[a + b])cout << 'R' << endl;
else cout << 'P' << '\n';
} else if (b + a == 2) cout << 'R' << '\n';
else if (!vis[a + c] && !vis[b + c])cout << 'R' << '\n';
else cout << 'P' << '\n';
}
}
}
return 0;
}
Problem D. "逆"天求和
主要就是读题,读懂题推出公式,就可以了,如果没有读懂公式可以通过打表找规律,因为如果直接求逆元会超时,可以先用快速幂求逆元,求出小范围的数据,从中找规律。
打表代码
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define fi first
#define se second
using namespace std;
const int N =100010;
int f[]{2,3,5,7,11,13,17,19,23,31,37};
int tt=0;
int qkpow(int a,int b,int mod){
int res = 1, t = a % mod;
while(b){
if(b & 1)
res = (res * t) % mod;
t = (t * t) % mod;
b >>= 1;
}
return res;
}
void solve() {
int n = f[tt++];
int sum = 0;
for (int i = 1; i < n; i++) {
sum += qkpow(i, n - 2, n);
}
cout << sum << ' ' << n << endl;
}
int32_t main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int h_h;
//cin >> h_h;
h_h = 10;
while (h_h--)solve();
return 0;
}
/*
1 2
3 3
10 5
21 7
55 11
78 13
136 17
171 19
253 23
465 31
*/
公式就是1到n-1的和,直接就是n*(n-1)/2;
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define fi first
#define se second
using namespace std;
const int N =100010;
void solve() {
int n;
cin >> n;
int sum = 0;
cout << n*(n-1)/2 << endl;
}
int32_t main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int h_h;
cin >> h_h;
//h_h = 1;
while (h_h--)solve();
return 0;
}
Problem E. 读中国数字
模拟题,注意把数字按照四个四个的操作即可,注意细节
#include<bits/stdc++.h>
//#define int long long
#define endl '\n'
#define fi first
#define se second
using namespace std;
const int N = 100010;
map<int,char> mp;
map<int,char> mp1;
void solve() {
string s;
cin >> s;
if (s == "0") {
cout << 0 << endl;
return;
}
string str;
mp[0] = 'K', mp[1] = 'B', mp[2] = 'T', mp[3] = '-';
vector<string> ans;
for (int i = (int) s.size() - 1; i >= 0; i--) {
str += s[i];
if (str.size() == 4) {
reverse(str.begin(), str.end());
ans.push_back(str), str.clear();
}
}
if ((int) str.size()) {
reverse(str.begin(), str.end());
ans.push_back(str);
}
reverse(ans.begin(), ans.end());
//for (auto i: ans)cout << i << ' ';cout<<endl;
string sans;
//cout << ans.size() << endl;
int cnt = (int) ans.size();
for (auto i: ans) {
string s1;
while (i.size() < 4)i = ' ' + i;
for (int j = 0; j < i.size(); j++) {
if (i[j] == ' ')continue;
if (i[j] == '0')s1 += i[j];
else if (i[j] != '0') {
s1 += i[j];
if (j != i.size() - 1)s1 += mp[j];
}
}
while (s1.back() == '0')s1.pop_back();
if (s1.size()) {
int ret = 0;
for (int i = 0; s1[i] == '0' && i < s1.size(); i++)ret++;
reverse(s1.begin(), s1.end());
while (s1.back() == '0' && ret > 1) s1.pop_back(), ret--;
reverse(s1.begin(), s1.end());
}
if (cnt == 3 && s1.size())s1 += 'Y';
if (cnt == 2 && s1.size())s1 += 'W';
cnt--;
sans += s1;
}
//cout<<sans<<endl;
for (int i = 0; i < sans.size() - 1; i++)if (sans[i] == '0' && sans[i + 1] == '0')sans[i] = '-';
for (auto i: sans) {
if (i == '-')continue;
cout << i;
}
cout << endl;
}
/*10
0
10
102
70308432
12003
900000000000
100000000001
100000100001
10101010101
20001001001
*/
int32_t main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int h_h;
cin >> h_h;
//getchar();
//h_h = 1;
while (h_h--)solve();
return 0;
}
Problem H. 我爱XTU
这个题就是先把每个字母的前缀和求出来,然后用map来存它出现的次数,把前缀和相等的统计次数,他对答案的贡献就是n*(n-1)/2,如果是0,0就说明回到了最开始的时候,要把次数加上1,最后输出ans即可。
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define fi first
#define se second
using namespace std;
const int N = 10010;
void solve() {
string s;
cin >> s;
map<pair<int, int>, int> mp1;
int sx[N]{}, st[N]{}, su[N]{};
int x = 0, t = 0, u = 0;
for (int i = 0; i < s.size(); i++) {
if (s[i] == 'X')x++, sx[i] = x;
else sx[i] = x;
if (s[i] == 'T')t++, st[i] = t;
else st[i] = t;
if (s[i] == 'U')u++, su[i] = u;
else su[i] = u;
}
int ans = 0;
for (int i = 0; i < s.size(); i++)mp1[{sx[i] - st[i], sx[i] - su[i]}]++;
for (auto &[a, b]: mp1) {
if (a.fi == 0 && a.se == 0)b++;
ans += b * (b - 1) / 2;
}
cout << ans << endl;
}
int32_t main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int h_h;
cin >> h_h;
//h_h = 1;
while (h_h--)solve();
return 0;
}