2017-2018 ACM-ICPC Asia East Continent League Final (ECL-Final 2017) Solution
A:Chat Group
题意:给出一个n, k 计算C(n, k) -> C(n,n) 的和
思路:k只有1e5 反过来想,用总的(2^ n) 减去 C(n, 0) -> C(n, k - 1), 预处理逆元,
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define ll long long 6 #define N 100010 7 8 const ll MOD = (ll)1e9 + 7; 9 10 int t; 11 ll n, k; 12 ll inv[N]; 13 14 inline void Init() 15 { 16 inv[1] = 1; 17 for (int i = 2; i < N; ++i) inv[i] = inv[MOD % i] * (MOD - MOD / i) % MOD; 18 } 19 20 inline ll qpow(ll x, ll n) 21 { 22 ll base = x; 23 ll ans = 1; 24 while (n) 25 { 26 if (n & 1) ans = (ans * base) % MOD; 27 base = base * base % MOD; 28 n >>= 1; 29 } 30 return ans; 31 } 32 33 int main() 34 { 35 Init(); 36 scanf("%d", &t); 37 for (int kase = 1; kase <= t; ++kase) 38 { 39 scanf("%lld%lld", &n, &k); 40 printf("Case #%d: ", kase); 41 if (k > n) 42 { 43 puts("0"); 44 continue; 45 } 46 ll ans = qpow(2, n); 47 ll tmp = 1; 48 for (int i = 0; i < k; ++i) 49 { 50 ans = (ans - tmp + MOD) % MOD; 51 tmp = tmp * (n - i) % MOD * inv[i + 1] % MOD; 52 } 53 printf("%lld\n", ans); 54 } 55 return 0; 56 }
B:Scapegoat
题意: 给出n件错误,每件错误的严重程度是ai, 有m只替罪羊,每只替罪羊只能承担一件事情的责任,如果多只替罪羊承担一件事情的责任,那么就是这多只替罪羊平均分担这件事情的责任,求每只替罪羊承担责任的方差
思路:当替罪羊总量固定的时候,那么平均值也是固定的,那么我们可以根据减少量排序,每次贪心取最大
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 200010 5 6 double ave; 7 8 struct node 9 { 10 int num; 11 double tot, cur, dis, gap; 12 inline bool operator < (const node &r) const 13 { 14 return gap < r.gap; 15 } 16 inline node() {} 17 inline node(double _tot, int _num, double _cur) 18 { 19 tot = _tot; num = _num; cur = _cur; 20 dis = (cur - ave) * (cur - ave) * num; 21 gap = dis - ((tot / (num + 1) - ave) * (tot / (num + 1) - ave)) * (num + 1); 22 } 23 }; 24 25 int t, n, m; 26 double arr[N]; 27 28 inline void Run() 29 { 30 scanf("%d", &t); 31 for (int kase = 1; kase <= t; ++kase) 32 { 33 printf("Case #%d: ", kase); 34 scanf("%d%d", &n, &m); 35 ave = 0; 36 for (int i = 1; i <= n; ++i) scanf("%lf", arr + i), ave += arr[i]; ave /= m; 37 priority_queue <node> q; 38 for (int i = 1; i <= n; ++i) 39 q.emplace(arr[i], 1, arr[i]); 40 for (int i = n + 1; i <= m; ++i) 41 { 42 node top = q.top(); q.pop(); 43 q.emplace(top.tot, top.num + 1, top.tot / (top.num + 1)); 44 } 45 double ans = 0; 46 for (int i = 1; i <= n; ++i) 47 { 48 node top = q.top(); q.pop(); 49 ans += top.dis; 50 } 51 ans /= m; 52 printf("%.10f\n", ans); 53 } 54 } 55 56 int main() 57 { 58 #ifdef LOCAL 59 freopen("Test.in", "r", stdin); 60 #endif 61 62 Run(); 63 64 return 0; 65 }
C:Traffic Light
题意:给出两个红绿灯之间的时间以及每个红绿灯的红扥和绿灯时间,求最小的最坏情况。
思路:当经过一个红灯的时候可以发现,可以通过调整OFFi来保证接下来都是绿灯,所以答案就是最大的红灯时间和路程
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 #define N 1010 6 7 double sum; 8 int n; 9 10 int main() 11 { 12 int t; 13 scanf("%d", &t); 14 for(int cas = 1; cas <= t; ++cas) 15 { 16 scanf("%d", &n); 17 sum = 0; 18 for(int i = 0; i <= n; ++i) 19 { 20 double x; 21 scanf("%lf", &x); 22 sum += x; 23 } 24 double tmp = 0; 25 for(int i = 1; i <= n; ++i) 26 { 27 double a, b; 28 scanf("%lf %lf", &a, &b); 29 tmp = max(tmp, b); 30 } 31 sum += tmp; 32 printf("Case #%d: %.10f\n", cas, sum); 33 } 34 return 0; 35 }
D:Mr. Panda and Geometric Sequence
留坑。
E:Snakebird
留坑。
F:Good Number
留坑。
G:Image Recognition
留坑。
H:Mr. Panda and Birthday Song
留坑。
I:PLAYERUNKNOWN'S BATTLEGROUNDS
留坑。
J:Straight Master
题意:给出n种牌的数量,你可以打出长度为3,4,5的顺子,问最后能否打完。
思路:345可以拼凑出所有大于等于3的数字。先构造出差分约束,将每一个正值贪心的与最近的负值匹配,贪心扫一遍即可
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 2e5 + 10; 6 7 int n; 8 int arr[maxn]; 9 int brr[maxn]; 10 11 int main() 12 { 13 int t; 14 scanf("%d", &t); 15 for (int cas = 1; cas <= t; ++cas) 16 { 17 scanf("%d", &n); 18 for (int i = 1; i <= n; ++i) 19 { 20 scanf("%d", arr + i); 21 } 22 arr[n + 1] = 0; 23 for (int i = 1; i <= n + 1; ++i) 24 { 25 brr[i] = arr[i] - arr[i - 1]; 26 } 27 bool flag = true; 28 int now = 0; 29 for (int i = 1; i <= n + 1; ++i) 30 { 31 while (brr[i] < 0 && now <= i - 3) 32 { 33 if (brr[now] + brr[i] >= 0) 34 { 35 brr[now] += brr[i]; 36 brr[i] = 0; 37 } 38 else 39 { 40 brr[i] += brr[now]; 41 brr[now] = 0; 42 } 43 if (brr[i] < 0) ++now; 44 } 45 if (brr[i] < 0) 46 { 47 flag = false; 48 break; 49 } 50 } 51 printf("Case #%d: %s\n", cas, flag ? "Yes" : "No"); 52 } 53 return 0; 54 }
K:Downgrade
题意:给出一个游戏里面,有主等级以及副等级,如果有一天没有打,那么它的等级就将主等级当成副等级,副等级满了可以生主等级
思路:虽然n很大,然后a只有1e5,可以知道最多下降到1-1就不会再变,然后二分找对应的主等级
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 const int N = 100000+10; 6 long long la[N],f[N]; 7 int main() { 8 long long t,p,i,j,l,r,k; 9 long long a,b,x,y,n,m; 10 scanf("%lld",&t); 11 p=0; 12 f[0]=0; 13 while (t--) { 14 ++p; 15 scanf("%lld%lld%lld",&a,&b,&n); 16 for (i=1;i<=a;++i) { 17 scanf("%lld",&la[i]); 18 f[i]=f[i-1]+la[i]; 19 } 20 x=a; y=b; 21 while (n--) 22 { 23 long long prex = x,prey = y; 24 int pos = lower_bound(f + 1, f + 1 + a, x) - f; 25 y = x - f[pos - 1]; x = pos; 26 if(x == prex && y == prey) break; 27 if(x == 1 && y == 1) break; 28 } 29 printf("Case #%lld: %lld-%lld\n",p,x,y); 30 } 31 return 0; 32 }
L:SOS
题意:给出n个格子,两个人轮流放'S' 或者 'O' 如果一个人放了之后,棋盘上出现"SOS" 它就赢了,Panda先手,求胜负关系或者平局
思路:有一个规律,当出现S__S 这样的局面的时候,谁第一步走进这个坑,谁就输了
找一下规律,16(lts)是一个分界点
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 int t, n; 6 7 int main() 8 { 9 scanf("%d", &t); 10 int d = 16; 11 for (int kase = 1; kase <= t; ++kase) 12 { 13 printf("Case #%d: ", kase); 14 scanf("%d", &n); 15 if (n < 7) 16 puts("Draw"); 17 else if (n < d) 18 puts((n & 1) ? "Panda" : "Draw"); 19 else 20 puts((n & 1) ? "Panda" : "Sheep"); 21 } 22 return 0; 23 }
M:World Cup
水。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define ll long long 6 7 int t, n; 8 ll price[10]; 9 10 int main() 11 { 12 scanf("%d", &t); 13 for (int kase = 1; kase <= t; ++kase) 14 { 15 for (int i = 1; i <= 5; ++i) scanf("%lld", price + i); 16 scanf("%d", &n); 17 ll ans = 0; 18 for (int i = 1, num; i <= n; ++i) 19 { 20 scanf("%d", &num); 21 if (num >= 1 && num <= 48) ans += price[1]; 22 else if (num >= 49 && num <= 56) ans += price[2]; 23 else if (num >= 57 && num <= 60) ans += price[3]; 24 else if (num >= 61 && num <= 62) ans += price[4]; 25 else ans += price[5]; 26 } 27 printf("Case #%d: %lld\n", kase, ans * 10000); 28 } 29 return 0; 30 }