2020 China Collegiate Programming Contest Qinhuangdao Site

A.A Greeting from Qinhuangdao

#include <bits/stdc++.h>

using namespace std;

int const N = 1e3 + 10;
typedef long long LL;

int n, T, m;
int c[N][N], kase = 1;
void init() {
for (int i = 0; i < N; ++i)
for (int j = 0; j <= i; ++j)
if (j == 0) c[i][j] = 1;
else c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]);
}

int gcd(int a,int b) {
return b == 0? a: gcd(b, a % b);
}

int main() {
//    freopen("in.txt", "r", stdin);
cin >> T;
init();
while(T--) {
cin >> n >> m;
//    	cout << n << " " << m << endl;
if (n == 1) {
printf("Case #%d: 0/1\n", kase++);
continue;
}
//    	cout << n << " " << m << endl;
int a = c[n + m][2];
int b = c[n][2];
//    	cout <<a << " " << b << endl;
int t = gcd(a, b);
a /= t, b /= t;
printf("Case #%d: %d/%d\n", kase++, b, a);
}
return 0;
}


D.Exam Results

#include <bits/stdc++.h>

using namespace std;

int const N = 5e5 + 10;
typedef long long LL;
typedef pair<int, int> PII;
int n, T, m, p, cnt[N], tot, kase = 1;
PII stu[N];

int main() {
cin >> T;
while(T--) {
tot = 0;
memset(cnt, 0, sizeof cnt);
scanf("%d%d", &n, &p);
for (int i = 1; i <= n; ++i) {
int a, b;
scanf("%d%d", &a, &b);
stu[tot++] = {a, i};
stu[tot++] = {b, i};
}

sort(stu, stu + tot);

int now = 0, tail = -1;
while(now != n) {  // 先要将n个人都选择进去
tail++;
cnt[stu[tail].second] ++;
if (cnt[stu[tail].second] == 1) now ++;
}

// 然后留下最后一个人
now --;
cnt[stu[tail].second] --;
tail--;

// 保证双指针的区间都是满足条件的
int head = 0, ans = 0;
while(tail < 2 * n - 1) {
tail++;
cnt[stu[tail].second]++;
if (cnt[stu[tail].second] == 1) now++;
while(head < tail && (LL)stu[head].first * 100 < (LL)stu[tail].first * p) {
}
ans = max(ans, now);
}
printf("Case #%d: %d\n", kase++, ans);
}
return 0;
}


E.Friendly Group

**题意： ** 给定n个点，要从n个点中选择k个点，增益为：k个点之间的所有连边数目 - 和这个k个点的连边且不属于这个集合的边数目 - k。

#include <bits/stdc++.h>

using namespace std;

int const N = 1e6 + 10, M = 4e6 + 10;
typedef long long LL;

int n, T, m;
int e[M], ne[M], h[N], idx, st[N], kase = 1, st2[M];
int m1, n1, flg;

void dfs(int u) {
for (int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if (!st2[i]) {
m1++;
st2[i] = st2[i ^ 1] = 1;
}
if (!st[j]) {
n1++;
st[j] = 1;
dfs(j);
}
}
return ;
}

void add(int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

int main() {
cin >> T;
while(T--) {
scanf("%d%d", &n, &m);
idx = 0;
for (int i = 1; i <= n; ++i) st[i] = 0, h[i] = -1;
for (int i = 0; i < 2 * m; ++i) st2[i] = 0;
for (int i = 1; i <= m; ++i) {
int a, b;
scanf("%d%d", &a, &b);
}
int res = 0;
for (int i = 1; i <= n; ++i) {
if (!st[i]) {
m1 = n1 = 0;
dfs(i);
res += max(0, m1 - n1);
}
}
printf("Case #%d: %d\n", kase++, res);
}
return 0;
}


F.Good Number

#include <bits/stdc++.h>

using namespace std;

int const N = 1e3 + 10;
typedef long long LL;

int n, T, k, kase = 1;

LL qmi(int a, int k) {
LL res = 1;
while(k) {
if (k & 1) res = res * a;
k >>= 1;
a =  (LL)a * a;
}
return res;
}

int main() {
cin >> T;
while(T--) {
cin >> n >> k;
if ( k == 1 || k > 30) {
printf("Case #%d: %d\n", kase++, n);
continue;
}
int l = 1, r = 1, cnt = 1;
LL res = 0;
while(1) {
if (r >= n || l >= n) break;
l = qmi(cnt, k);
r = min(qmi(cnt + 1, k) - 1, (LL)n);
//			cout << l << " " << r << endl;
res += (r / cnt) - (l / cnt);
if (l % cnt == 0) res++;
cnt++;
}
printf("Case #%d: %lld\n", kase++, res);
}
return 0;
}

/*
2
233 1
233 2
*/