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)
-----
posted @ 2022-04-11 17:03  ccz9729  阅读(187)  评论(0编辑  收藏  举报