第十一届北京邮电大学程序设计竞赛 - 热身赛 (1)
第十一届北京邮电大学程序设计竞赛 - 热身赛 (1)
注册新账号即可参加比赛(已被延长为3W分钟)
A.预处理筛出2^15以内的质数然后枚举计数即可
1 #include <cstdio> 2 3 int p[60000], v[60000]; 4 5 int main() { 6 for(int i = 2;i <= 50000;i ++) { 7 if(!v[i]) p[++ p[0]] = i; 8 for(int j = 1;j <= p[0] && 1ll * i * p[j] <= 50000;j ++) { 9 v[i * p[j]] = 1; 10 if(i % p[j] == 0) break; 11 } 12 } 13 int n, m; 14 while(scanf("%d", &n), n) { 15 m = 0; 16 for(int i = 2;i + i <= n;i ++) 17 if(!v[i] && ! v[n - i]) 18 m ++; 19 printf("%d\n", m); 20 } 21 return 0; 22 }
B.一个比较典型的背包问题
f[i]表示组成 i 元的方案数
然后分别用面值1 4 9 ... 289的coin更新17次就好了
1 #include <cstdio> 2 3 typedef long long ll; 4 5 const ll Mod = 1000000009; 6 7 int s[18]; 8 9 ll f[2222]; 10 11 int main() { 12 f[0] = 1; 13 for(int i = 1;i <= 17;i ++) 14 s[i] = i * i; 15 for(int j = 1;j <= 17;j ++) 16 for(int i = s[j];i <= 2000;i ++) 17 f[i] = (f[i] + f[i - s[j]]) % Mod; 18 int t, n; 19 scanf("%d", &t); 20 while(t --) { 21 scanf("%d", &n); 22 printf("%lld\n", f[n]); 23 } 24 return 0; 25 }
C.注意到题目描述最后一句
little Ding is concerned about the answer of every user's new friends
when that user is the only one who adds new friends
所以并不是并查集
直接枚举就好了,注意到为了防止一个人与自己建立新边并计入答案
我们一开始就设置好 i 和 i 自己是朋友即可
#include <cstdio> #include <vector> #include <cstring> #include <iostream> using namespace std; vector <int> e[1010]; int t, m, n, p, f[1010]; int main() { cin >> t; while(t --) { cin >> n >> m; for(int i = 1;i <= n;i ++) f[i] = 0, e[i].clear(); for(int u, v, i = 1;i <= m;i ++) { scanf("%d %d", &u, &v); e[u].push_back(v); e[v].push_back(u); } for(int i = 1;i <= n;i ++) { p = 0, f[i] = i; for(int j = 0;j < e[i].size();j ++) f[e[i][j]] = i; for(int j = 0;j < e[i].size();j ++) for(int u = e[i][j], k = 0;k < e[u].size();k ++) if(f[e[u][k]] != i) f[e[u][k]] = i, p ++; printf("%d\n", p); } } return 0; }
D.last[i]表示当 i 是选中的区间的最右端时,最左端可以在last[i] + 1的位置
pre[i]表示 ai 上一次出现的位置,初始化均为0
显然就有 last[i] = max(pre[j]), 1 <= j <= i
ans = max(i - last[i]). 1 <= i <= n
所以从左向右O(n)扫一遍即可
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 5 using namespace std; 6 7 int t, n, l, a, m, p[100010]; 8 9 int main() { 10 cin >> t; 11 while(t --) { 12 m = 1, l = 0; 13 cin >> n; 14 memset(p, 0, sizeof p); 15 for(int i = 1;i <= n;i ++) { 16 scanf("%d", &a); 17 if(p[a]) l = max(l, p[a]); 18 p[a] = i, m = max(m, i - l); 19 } 20 cout << m << endl; 21 } 22 return 0; 23 }
G.看样例xjb猜一下
分子是lcm,分母是gcd
然后就过了...
正确性简单证明:
要求n个分数的lcm
那么我们...嗨呀好麻烦自己脑补吧233
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 typedef long long ll; 6 7 vector <ll> a, b; 8 9 ll gcd(ll x, ll y) { 10 return y ? gcd(y, x % y) : x; 11 } 12 13 int main() { 14 int n; 15 ll x, y, X, Y; 16 while(~scanf("%d", &n)) { 17 a.clear(), b.clear(); 18 while(n --) { 19 scanf("%lld %lld", &x, &y); 20 a.push_back(x); 21 b.push_back(y); 22 } 23 X = a[0], Y = b[0]; 24 for(int i = 1;i < a.size();i ++) 25 X = X / gcd(X, a[i]) * a[i], Y = gcd(Y, b[i]); 26 printf("%lld %lld\n", X, Y); 27 } 28 return 0; 29 }