本来不打算写总结的,想来博客已经很久没更新了,觉得还是来一发吧。
赶脚这次比赛纯粹是运气好,基本上是沿着这样的模式:翻到一个题 → 嗯,有思路 → 敲一敲 → 提交 → 1A → 看下一道题 .... 所以噼里啪啦交了6道水题,所以中途没有卡在哪一道题上浪费时间,(除了E题第一次提交忘了开LL),幸运地最大化利用了时间,结果莫名其妙就2nd了.... (= =#
(PS:话说刚开场敲A的时候,一激动碰到了键盘右边的关机键,然后电脑就注销了。。销了。。了。。然后找了帅气的taos学长,让他帮我重发一下login和ranklist,所以当我过A的时候已经17分钟过去了。。现在想想真是可怕。。)
A题:签到题。
1 #include <stdio.h> 2 #include <string.h> 3 using namespace std; 4 5 int main() 6 { 7 int n; 8 while(~scanf("%d", &n)) 9 { 10 int sum = 0;int x; 11 for(int i =0 ; i < n; ++i) 12 scanf("%d", &x), sum += x; 13 printf("%d\n", sum); 14 } 15 return 0; 16 }
B题:比较裸的Lucas,直接上结论:C(n,r)=(n!)*(r!)^(P-2)*(n-r)!^(P-2)%P,至于证明我说过由费马小定理可以得出a和a^(P-2)在模P运算下互为逆元,因此得证。
1 #include <stdio.h> 2 #include <string.h> 3 using namespace std; 4 5 typedef long long LL; 6 const LL P = 1000000007; 7 LL f[110000]; 8 9 LL Pow(LL x, LL n) 10 { 11 LL ans = 1LL; 12 while(n) 13 { 14 if(n & 1) 15 ans = ((ans % P) * (x % P)) % P; 16 x = ((x % P) * (x % P)) % P; 17 n >>= 1; 18 } 19 return ans; 20 } 21 22 LL c(LL n, LL r) 23 { 24 return (f[n] % P) * ((Pow(f[r], P - 2) % P) * (Pow(f[n-r], P - 2) % P) % P) % P; 25 } 26 27 int main() 28 { 29 LL n; 30 while(~scanf("%I64d", &n)) 31 { 32 f[0] = 1LL; 33 f[1] = 1LL; 34 for(LL i = 2LL; i <= n; ++i) 35 f[i] = (f[i-1] % P * i) % P; 36 for(LL i = 0LL; i < n; ++i) 37 printf("%I64d ", c(n, i)); 38 printf("1\n"); 39 // LL m, r; 40 // scanf("%I64d%I64d", &m, &r); 41 // printf("%I64d\n", c(m, r)); 42 } 43 return 0; 44 }
C题:留坑待填,据说用DP,又据说暴力可过,没看到题目说最多分解成4项,QwQ。
D题:水题,把元素装进一个muiltiset里面,然后对于每个元素a,在其中查找s-a,然后对于s=2*a的情况特判一下即可。
1 #include <stdio.h> 2 #include <string.h> 3 #include <set> 4 using namespace std; 5 6 int a[110000]; 7 8 int main() 9 { 10 int t; 11 while(~scanf("%d", &t)) 12 { 13 while(t--) 14 { 15 multiset<int> ms; 16 ms.clear(); 17 int n, s; 18 scanf("%d", &n); 19 for(int i = 0; i < n; ++i) 20 scanf("%d", &a[i]), ms.insert(a[i]); 21 scanf("%d", &s); 22 23 bool flag = 0; 24 for(int i = 0; i < n; ++i) 25 { 26 // printf("%d\n", ms.count(s - a[i])); 27 if(ms.count(s - a[i]) != 0) 28 { 29 if(s != 2 * a[i]) 30 { 31 flag = 1; break; 32 } 33 else 34 { 35 if(ms.count(s - a[i]) >= 2) 36 { 37 flag = 1; break; 38 } 39 } 40 } 41 42 } 43 // 44 // multiset<int>::iterator it; 45 // for(it = ms.begin(); it != ms.end(); ++it) 46 // printf("%d ", *it); 47 // puts(""); 48 49 if(flag) puts("Yes"); 50 else puts("No"); 51 } 52 } 53 return 0; 54 }
E题:水题,本来封榜之后准备弃疗,然后看了下这个题,觉得好像可以搞一搞,然后发现是个大水题,2333....关键就是由∑((xi-xj)^2+(yi-yj)^2) 化为 (n-1)(∑xi^2+∑yi^2)+∑xi*(sn-si)+∑yi*(tn-yi)即可,(其中si=∑xi,ti=∑yi),复杂度由O(n^2)降为O(n)。
1 #include <stdio.h> 2 using namespace std; 3 4 typedef long long LL; 5 const int N = 110000; 6 LL a[N], b[N], sum1[N], sum2[N]; 7 8 int main() 9 { 10 int n; 11 while(~scanf("%d", &n)) 12 { 13 LL tep1 = 0, tep2 = 0; 14 sum1[0] = 0, sum2[0] = 0; 15 for(int i = 1; i <= n; ++i) 16 { 17 scanf("%I64d%I64d", &a[i], &b[i]); 18 tep1 += a[i] * a[i]; 19 tep2 += b[i] * b[i]; 20 sum1[i] = sum1[i-1] + a[i]; 21 sum2[i] = sum2[i-1] + b[i]; 22 } 23 24 LL tep3 = (n - 1) * (tep1 + tep2); 25 26 LL tep4 = 0, tep5 = 0; 27 for(int i = 1; i < n; ++i) 28 tep4 += a[i] * (sum1[n] - sum1[i]); 29 for(int i = 1; i < n; ++i) 30 tep5 += b[i] * (sum2[n] - sum2[i]); 31 32 LL ans = tep3 - 2 * (tep4 + tep5); 33 printf("%I64d\n", ans); 34 } 35 return 0; 36 }
F题:水过去的,用抛物线方程跟墙的方程联立,没啥可说的。
1 #include <stdio.h> 2 #include <string.h> 3 #include <math.h> 4 #include <algorithm> 5 using namespace std; 6 7 const double g = 9.8; 8 double a[11000]; 9 10 struct Wall 11 { 12 double x, y; 13 } w[110000], ans[11000]; 14 15 bool cmpx(Wall a, Wall b) 16 { 17 return a.x < b.x; 18 } 19 20 int main() 21 { 22 // freopen("f.txt", "w", stdin); 23 int n; 24 double v; 25 while(~scanf("%d%lf", &n, &v)) 26 { 27 for(int i = 0; i < n; ++i) 28 scanf("%lf", &a[i]); 29 int m; 30 scanf("%d", &m); 31 for(int i = 0 ; i < m; ++i) 32 scanf("%lf%lf", &w[i].x, &w[i].y); 33 sort(w, w + m, cmpx); 34 35 for(int i = 0; i < n; ++i) 36 { 37 double vx, vy, h, x0, d; 38 vx = v * cos(a[i]); 39 vy = v * sin(a[i]); 40 h = vy * vy / (2.0 * g); 41 x0 = v * v * sin(2.0 * a[i]) / g; 42 d = 2.0 * vy * vy / (g * x0 * x0); 43 bool flag = 0; 44 for(int j = 0; j < m; ++j) 45 { 46 double yt = -d * w[j].x * (w[j].x - x0); 47 if(0 <= yt && yt <= w[j].y) 48 { 49 ans[i].x = w[j].x, ans[i].y = yt; 50 flag = 1; 51 break; 52 } 53 } 54 if(!flag) 55 ans[i].x = x0, ans[i].y = 0; 56 } 57 58 for(int i = 0; i < n; ++i) 59 printf("%.6f %.6f\n", ans[i].x,ans[i].y); 60 } 61 return 0; 62 }
G题:留坑待填,据说用高斯消元。
H题:简单的公式题,palapala一顿搞,结果就是ans=2*v*T^2/t,没啥可说的。
1 #include <stdio.h> 2 #include <string.h> 3 using namespace std; 4 5 int main() 6 { 7 double T, v, t; 8 while(~scanf("%lf%lf%lf", &T, &v, &t)) 9 { 10 double ans = 2 * v * T * T / t; 11 printf("%.5f\n", ans); 12 } 13 return 0; 14 }
I题:模拟题,嫌题目太啰嗦没看,留坑待填。
J题:离散+博弈,居然有人过,orz....,留坑待填。
以上。