牛客IOI周赛20-普及组 题解
难得有一场ak了,写一下自己的做法吧
完全数
支持
做法,直接根号内试除统计即可。
读入用
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e5 + 5;
const int mod = 998244353;
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
ll n; cin >> n;
ll ans = 0;
for(ll i = 2; i * i <= n; i++) {
if(n % i == 0) {
ans += n / i;
ans += i;
if(n / i == i) ans -= i;
}
}
ans++;
if(ans == n) {
cout << "Pure\n";
} else if(ans > n) {
cout << "Late\n";
} else {
cout << "Early\n";
}
return 0;
} 移动撤销
如果不是 对于每个操作改变
坐标,把相应操作丢到栈里
如果是 ,栈空时不管,否则取出栈首元素,反着改变它的
坐标
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e5 + 5;
const int mod = 998244353;
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int n; cin >> n;
string s; cin >> s;
stack<char> st;
int l = 0, r = 0;
for(auto & x : s) {
if(x == 'W') {
r++;
st.push(x);
} else if(x == 'A') {
l--;
st.push(x);
} else if(x == 'S') {
r--;
st.push(x);
} else if(x == 'D') {
l++;
st.push(x);
} else if(x == 'Z') {
if(!st.empty()) {
auto tmp = st.top(); st.pop();
if(tmp == 'W') {
r--;
//st.push('S');
} else if(tmp == 'A') {
l++;
//st.push('D');
} else if(tmp == 'S') {
r++;
//st.push('W');
} else if(tmp == 'D') {
l--;
//st.push('A');
}
}
}
//cout << l << ' ' << r << '\n';
}
cout << l << ' ' << r << '\n';
return 0;
} 石头剪刀布
不知道第几遍做这个题了
贪心,先算牛牛能赢牛妹的,每次取对应方案的min就可以统计出来,然后把对应的石头剪刀布次数减去。最后再计算平手的就可以了。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e5 + 5;
int a[N], b[N];
const int mod = 998244353;
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int n; cin >> n;
for(int i = 1; i <= 3; i++) cin >> a[i];
for(int i = 1; i <= 3; i++) cin >> b[i];
int ans = 0;
int num1 = min(a[1], b[2]);
a[1] -= num1, b[2] -= num1;
ans += num1 * 2;
//cout << ans << endl;
int num2 = min(a[2], b[3]);
a[2] -= num2, b[3] -= num2;
ans += num2 * 2;
//cout << ans << endl;
int num3 = min(a[3], b[1]);
a[3] -= num3, b[1] -= num3;
ans += num3 * 2;
//cout << ans << endl;
cout << ans + min(a[1], b[1]) + min(a[2], b[2]) + min(a[3], b[3]) << '\n';
return 0;
} 夹缝中求和
对于不等式 做变换得到
那么先对序列排序,枚举每个 ,在序列上二分找到
的符合条件数字就可以了。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e5 + 5;
int a[N];
const int mod = 998244353;
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int n, x, y; cin >> n >> x >> y;
for(int i = 1; i <= n; i++) {
cin >> a[i];
}
sort(a + 1, a + 1 + n);
ll ans = 0;
for(int i = 1; i <= n; i++) {
int l = x - a[i];
int r = y - a[i];
int posl = lower_bound(a + 1 + i, a + 1 + n, l) - a - 1;
int posr = upper_bound(a + 1 + i, a + 1 + n, r) - a - 1;
posr--;
ans += posr - posl + 1;
}
cout << ans << '\n';
return 0;
}
查看18道真题和解析