2020ICPC 江西省大学生程序设计竞赛
A A Simple Math Problem
莫反 不会(
B Apple
签到题
点击查看代码
T = int(input())
for i in range (T):
n, m = map(int, input().split())
# n * (n + 1) / 2
p = m * (m + 1) / 2
if n >= p :
print("possible")
else :
print("impossible")
# 1 2 3 4
C Charging
二分答案
点击查看代码
#include <stdio.h>
#include <vector>
#define N 300001
#define ll long long
int n, m, r[N];
std::vector<int> l[N];
bool check(int len) {
for(int i = 1; i <= n; i ++ ) r[i] = 0;
int tot = 0; // i + len - 1 <= n
for(int i = 1; i + len - 1 <= n; i ++ ){
for(int &it: l[i]) {
if(it >= i + len - 1) {
++ tot;//如果左端点为 i 的区间,右端点比 i + len - 1 大,那么需要加上这个区间
++ r[it]; //为了方便删去这个区间的贡献
}
}
if(tot >= len) return true;
tot -= r[i + len - 1]; //区间右端点为 i + len - 1 的区间一定是没有用的
}
return false;
}
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i ++ ) {
int L, R; scanf("%d%d", &L, &R);
l[L].push_back(R);
}
int l = 0, r = n;
while(l < r) {
int mid = (l + r + 1) >> 1;
if(check(mid)) l = mid;
else r = mid - 1;
}
printf("%d\n", l);
return 0;
}
D Chinese Valentine's Day
sam 后缀自动机 不会(
E Color Sequence
状态压缩
考虑颜色只有20种,因此我们可以用一个数字的二进制去存储每个点之前的所有颜色的个数的奇偶性
因此我们可以利用前缀和的思想去枚举左端点,寻找合法右端点的个数,然后删除这个点的贡献即可
点击查看代码
#define ll long long
#define rep(i, a, b) for(int i(a); i <= b; ++ i)
const int N = 1e6 + 10, M = 21;
int a[N];
int n;
int cnt[1 << M];
void solve() {
cin >> n;
int flag = 0;
int now = 0;
rep(i, 1, n) {
cin >> a[i];
now ^= (1 << a[i]);
cnt[now] ++;
}
ll ans = 0;
now = 0;
rep(i, 1, n) {
ans += cnt[now];
now ^= (1 << a[i]);
cnt[now] --;
}
cout << ans;
}
F Magical Number
简单 \(DFS\)
要用高精度,因此可以用 python
点击查看代码
list = [6, 2, 5, 5, 4, 5, 6, 3, 7, 6]
n = int(input())
def max(a, b) :
if a >= b :
return a
else :
return b
def dfs(idx, cntd, now) :
ret = -1
if cntd > n :
return -1
elif cntd == n :
return now
elif n - cntd == 1:
return -1
for i in range (10):
if now == 0 and i == 0 :
continue
x = list[i]
if (i + now * 10) % (idx + 1) == 0 and n - cntd >= x:
ret = max(dfs(idx + 1, cntd + x, now * 10 + i), ret)
return ret
ans = dfs(0, 0, 0)
print(ans)
G Mathematical Practice
...
I Simple Math Problem
找规律填数字
点击查看代码
#include <bits/stdc++.h>
#define rep(i, a, b) for(int i(a); i <= b; ++ i)
#define ll long long
using namespace std;
void solve() {
ll n, a, b; cin >> n >> a >> b;
ll sum = n * (n + 1) / 2 - 1;
ll lie = a + b + 1; //第 a + b + 1 列
if(a + b + 1 <= n) {
ll e = (lie - 1) * lie / 2;
e += a;
cout << e;
} else {
ll x = a + 1;
x -= (a + b + 1 - n); //加x就可以了
//
ll enD = n - 1;
ll start = a + b + 1 - n - 1;
start = n - start;
// start = n - start;
// cout << start << " " << enD << "\n";
ll S = (start + enD) * (enD - start + 1) / 2;
// cout << "x = " << x << "\n";
// cout << S << "\n";
S += x;
// cout << sum << "\n";
cout << S + sum;
//a + b + 1 列 就是 a + b + 1
}
//
// last --;
// ll lie = a + b;
// if(lie <= n) {
// ll e = lie * (lie + 1) / 2;
// e += b;
// cout << e;
// } else {
// //n + 1 a + b
// ll ans = (n + 1 + a + b) * (a + b - n - 1) / 2;
// ans +=
// }
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
solve();
return 0;
}
J Split Game
...
K Travel Expense
\(Floyed\) + 二分
点击查看代码
#include <bits/stdc++.h>
#define rep(i, a, b) for(int i(a); i <= b; ++ i)
#define ll long long
using namespace std;
const int N = 110;
int f[N][N];
ll chk(ll x, ll y, ll b) {
ll sum = 0, flag = 1;
for(int i = 1; i <= y; i ++ ) {
flag *= x;
sum += flag;
if(sum > b) return sum;
}
return sum;
}
void solve() {
int n, m; scanf("%d%d", &n, &m);
memset(f, 0x3f, sizeof f);
rep(i, 1, m) {
int u, v; scanf("%d%d", &u, &v);
f[u][v] = f[v][u] = 1;
}
for(int k = 1; k <= n; k ++ ) {
for(int l = 1; l <= n; l ++ ) {
for(int r = 1; r <= n; r ++ ) {
f[l][r] = min(f[l][r], f[l][k] + f[k][r]);
}
}
}
int q; scanf("%d", &q);
while(q -- ) {
ll s, t, b; scanf("%lld%lld%lld", &s, &t, &b);
ll l = 0, r = 1e9 + 10;
ll ans = 0;
while(l < r) {
ll mid = (l + r + 1) / 2;
ll ret = chk(mid, f[s][t], b);
if(ret > b) {
r = mid - 1;
} else {
l = mid;
}
// if(ret <= b) {
// ans = max(ans, mid);
// }
}// 二分 mid 是否符合条件
//mid + mid^2 + mid^3 + mid^4 .... mid^dist
printf("%lld\n", l);
}
}
int main() {
solve();
return 0;
}
L WZB's Harem
状压 \(DP\)
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define N 21
#define MOD 1000000007
#define ll long long
#define rep(i, a, b) for(int i(a); i <= b; ++ i)
#define dec(i, a, b) for(int i(a); i >= b; -- i)
int a[N];
ll dp[N][1 << N];
int main() {
int n; scanf("%d", &n);
rep(i, 1, n) {
rep(j, 0, n - 1) {
int x; scanf("%d", &x);
if(!x) a[i] |= (1 << j);
}
}
rep(i, 0, n - 1) if(a[1] >> i & 1) {
dp[1][1 << i] = 1;
}
rep(i, 2, n) {
rep(j, 0, n - 1) if(a[i] >> j & 1) {
rep(state, 0, (1 << n) - 1) if(dp[i - 1][state] && ((state >> j & 1) == 0)) {
ll &ret = dp[i][state | (1 << j)];
ret += dp[i - 1][state];
ret %= MOD;//0 1 -> 1 1
}
}
}
ll ret = dp[n][(1 << n) - 1];
rep(i, 1, n) {
ret = ret * i % MOD;
}
printf("%lld\n", ret);
//dp[i][state] 表示前i行,且第i行的状态是 state 的方案数
return 0;
}
M Zoos's Animal Codes
字符串拼接
点击查看代码
n = input()
m = input()
print(n + m)