A
A - Dunaihttps://codeforces.com/gym/104023/problem/A
签到题,分别记录每个位置所有出现的选手数量,另外处理一个每个位置的冠军数量。
贪心地每队分配一个冠军选手,看是否可行,如果不可行,则可以直接输出所有位置中最小选手数量(木桶效应)
可以模拟,也可以直接推理出答案
ACcode
#include <iostream>
#include<cstring>
#include<algorithm>
#include<sstream>
#include<cmath>
#include<queue>
#include<set>
#include<vector>
#include<map>
#include<unordered_map>
#define endl '\n'
#define int unsigned long long
#define lowbit(x) (x &-x)
#define mh(x) memset(x, -1, sizeof h)
#define debug(x) cerr << #x << "=" << x << endl;
#define brk exit(0);
using namespace std;
void inline TLE() { ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); }
const int N = 2e6 + 50;
const int M = 2 * N;
const int mod = 998244353;
const double esp = 1e-6;
const double pi = acos(-1);
typedef pair<int, int> PII;
typedef long long ll;
set<string>st;
int cnt1[N], cnt2[N];
signed main()
{
int n;
cin >> n;
for (int i = 1;i <= n;i++) {
for (int j = 1;j <= 5;j++) {
string s;cin >> s;
st.insert(s);
}
}
int m;
cin >> m;
while (m--) {
string s;int x;
cin >> s >> x;
cnt1[x]++;
if (st.count(s)) {
cnt2[x]++;
}
}
int max1 = cnt2[1] + cnt2[2] + cnt2[3] + cnt2[4] + cnt2[5];//贪心地让每个冠军选手分配到不同队伍
int max2 = min({ cnt1[1],cnt1[2],cnt1[3],cnt1[4],cnt1[5] });
cout << min(max1, max2) << endl;
return 0;
}
模拟
ACcode
#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
const int N = 1e5 + 10;
using namespace std;
struct node {
int m, id;
};
vector<node> v;
int a[10], b[N];
set<string> mp;
typedef pair<int, int> PII;
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= 5; j++) {
string x;
cin >> x;
mp.insert(x);
}
}
int m;
cin >> m;
for (int i = 1; i <= m; i++) {
string s;
int x;
cin >> s >> x;
if (!mp.count(s))
a[x]++;
else
b[x]++;
}
for (int i = 1; i <= 5; i++) {
int mi = b[i];
for (int j = 1; j <= 5; j++) {
if (j == i) continue;
mi = min(mi, a[j]);
}
v.push_back({ mi, i });
}
sort(v.begin(), v.end(), [](node a, node b) { return a.m > b.m; });
int res = 0;
for (int i = 0; i < 5; i++) {
while (b[v[i].id] > 0) {
b[v[i].id]--;
int f = 0;
for (int j = 1; j <= 5; j++) {
if (j == v[i].id) continue;
if (a[j] == 0) {
if (b[j] != 0)
b[j]--;
else {
f = 1;
break;
}
}
else
a[j]--;
}
if (f == 1) break;
res++;
}
}
cout << res << endl;
}
C
C - Grasshttps://codeforces.com/gym/104023/problem/C先固定4个点,O(n)寻找一个和他们不共线的点,如果找不到则必然没有可行解,如果找到,则判断一下哪一个点是中心点。这里注意用pair<int,int>来保存分子分母以防止double精度损失使答案错误。
Accode
#include <iostream>
#include<cstring>
#include<algorithm>
#include<sstream>
#include<cmath>
#include<queue>
#include<bitset>
#include<vector>
#include<map>
#include<set>
#define endl '\n'
#define int long long
#define lowbit(x) (x &-x)
#define mh(x) memset(x, -1, sizeof h)
#define debug(x) cerr << #x << "=" << x << endl;
#define brk exit(0);
using namespace std;
void inline TLE() { ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); }
const int N = 2e6 + 50;
const int M = 2 * N;
const int mod = 998244353;
const double esp = 1e-6;
const double pi = acos(-1);
typedef pair<int, int> PII;
typedef long long ll;
struct node {
int x, y;
};
void solve()
{
int n;cin >> n;
vector<node>a(n + 1);
for (int i = 1;i <= n;i++) {
int x, y;
cin >> x >> y;
a[i].x = x;a[i].y = y;
}
auto check = [&](int j) {
set<PII>K;
for (int i = 1;i <= 4;i++) {
int x = a[i].x - a[j].x;
int y = a[i].y - a[j].y;
int t = __gcd(x, y);
x /= t;y /= t;
K.insert({ x,y });
}
return K.size() > 1;
};
auto find = [&]() {
for (int i = 1;i <= 5;i++) {
set<PII>K;
for (int j = 1;j <= 5;j++) {
if (i == j)continue;
int x = a[i].x - a[j].x;
int y = a[i].y - a[j].y;
int t = abs(__gcd(x, y));
x /= t;y /= t;
K.insert({ x,y });
}
if (K.size() == 4)return i;
}
return 1ll;
};
for (int i = 5;i <= n;i++) {
if (check(i)) {
swap(a[i], a[5]);
int t = find();
cout << "YES" << endl;
cout << a[t].x << " " << a[t].y << endl;
for (int i = 1;i <= 5;i++) {
if (i == t)continue;
cout << a[i].x << " " << a[i].y << endl;
}
return;
}
}
cout << "NO" << endl;
}
signed main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;t = 1;
cin >> t;
while (t--) {
solve();
}
return 0;
}
/*
101010
010101
*/
E
Python Will be Faster than C++https://codeforces.com/gym/104023/problem/E签到
ACcode
#include <iostream>
#include<cstring>
#include<algorithm>
#include<sstream>
#include<cmath>
#include<queue>
#include<bitset>
#include<vector>
#include<map>
#include<unordered_map>
#define endl '\n'
#define lowbit(x) (x &-x)
#define mh(x) memset(x, -1, sizeof h)
#define debug(x) cerr << #x << "=" << x << endl;
#define brk exit(0);
using namespace std;
void inline TLE(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);}
const int N = 2e5 + 10;
const int M = 2 * N;
const int mod = 998244353;
const double esp = 1e-6;
const double pi = acos(-1);
typedef pair<int, int> PII;
typedef long long ll;
int a[N];
int cnt[2];
void solve() {
int n, k;
cin >> n>>k;
for (int i = 1;i <= n;i++)cin >> a[i];
for (int i = 1;i <= n;i++) {
if (a[i] < k) {
cout << "Python 3." << i << " will be faster than C++" << endl;
return;
}
}
int i = n;
int res = n+1;
int x = a[n], y = a[n - 1];
while (2 * x - y >= k) {
if (2 * x - y >= x) {
cout << "Python will never be faster than C++" << endl;
return;
}
int t = x;
x = 2 * x - y;
y = t;
res++;
}
cout << "Python 3." << res << " will be faster than C++" << endl;
}
signed main() {
int t = 1;
while (t--)
{
solve();
}
return 0;
}
G
G - Grade 2https://codeforces.com/gym/104023/problem/G通过打表找规律会发现对于每个x的结果是不断循环的,循环节长度是大于等于x的2的倍数。
通过前缀和统计循环节内gcd为1的个数,然后找到所给区间含有的循环节个数,再处理一下两个边界的值,即可O(1)获取答案。
#include <iostream>
#include<cstring>
#include<algorithm>
#include<sstream>
#include<cmath>
#include<queue>
#include<bitset>
#include<vector>
#include<map>
#include<unordered_map>
#define endl '\n'
#define int unsigned long long
#define lowbit(x) (x &-x)
#define mh(x) memset(x, -1, sizeof h)
#define debug(x) cerr << #x << "=" << x << endl;
#define brk exit(0);
using namespace std;
void inline TLE() { ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); }
const int N = 2e6 + 50;
const int M = 2 * N;
const int mod = 998244353;
const double esp = 1e-6;
const double pi = acos(-1);
typedef pair<int, int> PII;
typedef long long ll;
int n, m;
int a[N], sum[N];
void solve()
{
int x, m;
cin >> x>>m;
int y = 1;
while (y < x) {
y *= 2;
}
int cnt = 0;
for (int i = 1;i <= y;i++) {
if (__gcd(i * x ^ x, x) == 1) {
a[i] = 1;
}
sum[i] = sum[i - 1] + a[i];
}
while (m--) {
int l, r;
cin >> l >> r;
l--;
int res1 = sum[l % y] + 1ll * (l / y) * sum[y];
int res2 = sum[r % y] + 1ll * (r / y) * sum[y];
cout << res2-res1 << endl;
}
}
signed main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;t = 1;
while (t--) {
solve();
}
return 0;
}
/*
101010
010101
*/
J
J - Eat, Sleep, Repeathttps://codeforces.com/gym/104023/problem/J
只需统计一下所有可以进行的操作数是奇数还是偶数即可得到答案。用map统计每个数的限制,将数组排序,从前想后扫,每个数可以减小的空间是第一个小于等于它的无限制或者是个数未达到上限的值,用一个小根堆去维护所有可行位置。(如果x限制数为0(map[x]=0),则可行位置是x+1)
#include <iostream>
#include<cstring>
#include<algorithm>
#include<sstream>
#include<cmath>
#include<queue>
#include<bitset>
#include<vector>
#include<map>
#include<unordered_map>
#define int long long
#define endl '\n'
#define lowbit(x) (x &-x)
#define mh(x) memset(x, -1, sizeof h)
#define debug(x) cerr << #x << "=" << x << endl;
#define brk exit(0);
using namespace std;
void inline TLE(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);}
const int N = 2e5 + 10;
const int M = 2 * N;
const int mod = 998244353;
const double esp = 1e-6;
const double pi = acos(-1);
typedef pair<int, int> PII;
typedef long long ll;
int a[N];
void solve() {
map<int, int>mp;
int n, k;
cin >> n >> k;
priority_queue<int, vector<int>, greater<int>>q;
q.push(0);
for (int i = 1;i <= n;i++)cin >> a[i];
while (k--) {
int x, y;cin >> x >> y;
if (y == 0)
q.push(x + 1);
else mp[x] = y;
}
int res = 0;
sort(a + 1, a + 1 + n);
int t = 0;
for (int i = 1;i <= n;i++) {
while (q.size() && q.top() <= a[i]) {
t = q.top();
q.pop();
}
res ^= (a[i] - t)&1;//只需统计奇偶即可
mp[t]--;
if (mp[t] == 0)q.push(t + 1);
}
if (res)cout << "Pico" << endl;
else cout << "FuuFuu" << endl;
}
signed main() {
int t;t = 1;
cin >> t;
while (t--)
solve();
return 0;
}