总是要面对的东西,逃不过。
这篇包含两个部分,竞赛与学习
希望自己能在2019加倍努力。
Part1:NOIP2018
先上成绩:
FJ - 0963 :T1 :100 T2:22 T3:12 T4:0
Total :134 福建省二等奖
T1:标题统计
考场代码:
1 #include <cstdio> 2 3 int main() { 4 //freopen("a.in","r",stdin); 5 int ans = 0; 6 char v = getchar(); 7 while (v != EOF) { 8 if (v != ' ' && v != ' ') { 9 ans++; 10 } 11 v = getchar(); 12 } 13 printf("%d",ans); 14 return 0; 15 }
AC代码同上,这题是入门题,并没有出现太大的问题。
T2:龙虎斗
考场代码:
1 #include <cstdio> 2 #include <iostream> 3 #include <cmath> 4 #include <cstring> 5 #include <cctype> 6 #define ll unsigned long long 7 using namespace std; 8 9 ll read() { 10 ll a = 0,f = 1; 11 char v = getchar(); 12 while (!isdigit(v)) { 13 if (v == '-') { 14 f = -1; 15 } 16 v = getchar(); 17 } 18 while (isdigit(v)) { 19 a = a * 10 + v - 48; 20 v = getchar(); 21 } 22 return a * f; 23 } 24 25 ll c[100010]; 26 int main() { 27 freopen("fight.in","r",stdin); 28 freopen("fight.out","w",stdout); 29 ll n = read(); 30 for (ll i = 1;i <= n;i++) { 31 c[i] = read(); 32 } 33 ll m = read(),p1 = read(),s1 = read(),s2 = read(); 34 ll lsum = 0,rsum = 0; 35 for (int i = 1;i <= n;i++) { 36 if (i == m) { 37 continue; 38 } 39 if (i < m) { 40 lsum += c[i] * (m-i); 41 } 42 if (i > m) { 43 rsum += c[i] * (i-m); 44 } 45 } 46 if (p1 > m) lsum += s1 * (m - p1); 47 if (p1 < m) rsum += s1 * (p1 - m); 48 ll nlsum = lsum,nrsum = rsum,bh = n,small = abs(lsum - rsum); 49 for (int i = 1;i <= n;i++) { 50 if (i == m) { 51 left == false; 52 } 53 if (i < m) { 54 nlsum = lsum + s2 * (m-i); 55 if ((abs(nlsum - nrsum) < small) || ((abs(nlsum - nrsum)) == small && i < bh)) { 56 bh = i; 57 small = abs(nlsum - nrsum); 58 } 59 } 60 if (i > m) { 61 nrsum = rsum + s2 * (i-m); 62 if ((abs(nlsum - nrsum) < small )|| ((abs(nlsum - nrsum)) == small && i < bh)) { 63 bh = i; 64 small = abs(nlsum - nrsum); 65 } 66 } 67 } 68 cout << bh; 69 fclose(stdin); 70 fclose(stdout); 71 return 0; 72 }
槽点过多,一点一点来分析:
- 对于数据类型并不熟悉,导致考场上写了unsigned long long(被玩了很久的梗),还写了abs,这个其实可以直接导致CE,还好没有,给了我20分
- 主过程完全不知道在干嘛,完全就是可以说瞎写的,并不是说不会写,考场上思路乱掉了
- 考后拿了100分
这一题其实是我最想打自己的一道题,本来可以拿100分的,但是由于各种原因拿到了这个分数。说明对于模拟类的题还是要细心。
AC代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cctype> 4 using namespace std; 5 typedef long long ll; 6 const int MAXN = 100010; 7 8 ll read() { 9 ll a = 0,f = 1; 10 char v = getchar(); 11 while (!isdigit(v)) { 12 if (v == '-') { 13 f = -1; 14 } 15 v = getchar(); 16 } 17 while (isdigit(v)) { 18 a = a * 10 + v - 48; 19 v = getchar(); 20 } 21 return a * f; 22 } 23 24 ll myabs(ll a) { 25 if (a < 0) { 26 return -a; 27 } 28 else { 29 return a; 30 } 31 } 32 33 ll c[MAXN],l,r,m,s1,r1,s2,n,sma,loc; 34 35 int main() { 36 n = read(); 37 for (ll i = 1;i <= n;i++) { 38 c[i] = read(); 39 } 40 m = read(); r1 = read(); s1 = read(); s2 = read(); 41 for (ll i = 1;i < m;i++) { 42 l += c[i] * (m - i); 43 } 44 for (ll i = m+1;i <= n;i++) { 45 r += c[i] * (i - m); 46 } 47 if (r1 > m) { 48 r += s1 * (r1 - m); 49 } 50 if (r1 < m) { 51 l += s1 * (m - r1); 52 } 53 sma = myabs(l-r); 54 loc = m; 55 for (int i = 1;i <= m;i++) { 56 if (sma > myabs((l+s2*(m-i))-r) || (sma == myabs((l+s2*(m-i))-r) && i < loc)) { 57 sma = myabs((l+s2*(m-i))-r); 58 loc = i; 59 } 60 } 61 for (int i = m+1;i <= n;i++) { 62 if (sma > myabs((r+s2*(i-m))-l) || (sma == myabs((r+s2*(i-m))-l) && i < loc)) { 63 sma = myabs((r+s2*(i-m))-l); 64 loc = i; 65 } 66 } 67 cout << loc; 68 return 0; 69 }
T3:摆渡车
我从XDFZ一路打到南天门,却倒在了一辆人大附中的摆渡车前——zzl
考场上明白了什么是学长说的所谓“膀胱题”(上厕所越多越有思路)
考场代码:
1 #include <cstdio> 2 #include <cctype> 3 #include <algorithm> 4 using namespace std; 5 6 inline int read() { 7 int a = 0,f = 1; 8 char v = getchar(); 9 while (!isdigit(v)) { 10 if (v == '-') { 11 f = -1; 12 } 13 v = getchar(); 14 } 15 while (isdigit(v)) { 16 a = a * 10 + v - 48; 17 v = getchar(); 18 } 19 return a * f; 20 } 21 22 inline bool cmp (int a,int b) { 23 return a < b; 24 } 25 int t[501]; 26 int main() { 27 //freopen("bus.in","r",stdin); 28 //freopen("bus.out","w",stdout); 29 int n = read(),m = read(); 30 for (int i = 1;i <= n;i++) { 31 time[i] = read(); 32 } 33 sort(t+1,t+1+n,cmp); 34 int rs = 0,timea = 0,last = 1,dd = 0; 35 for (int i = 1;i <= n;i++) { 36 timea = min(timea + m,timea + (m - (time[i+1] - time[i]))); 37 for (int j = last;j <= n;j++) { 38 if (timea >= t[j]) { 39 dd += timea - t[j]; 40 } 41 if (timea < t[j]) { 42 last = j; 43 break; 44 } 45 } 46 } 47 printf("%d",dd); 48 //fclose(stdin); 49 //fclose(stdout); 50 return 0; 51 }
考场去了N次厕所,还是没有推出转移方程,最后只能打了一个大样例通不过的贪心,意料之外拿了12分。
对于DP还是需要多加练习。
AC代码:
1 #include <cstdio> 2 #include <algorithm> 3 4 const int maxT = 4000105; 5 6 int n, m, t, ti, ans = 1e9, l = 1, r, cnt[maxT], sum[maxT], q[maxT], f[maxT]; 7 8 inline double getSlope(int u, int v) { return (double) (f[v] + sum[v] - f[u] - sum[u]) / (cnt[u] == cnt[v] ? 1e-9 : cnt[v] - cnt[u]); } 9 10 int main() { 11 scanf("%d%d", &n, &m); 12 for (int i = 1; i <= n; i++) { 13 scanf("%d", &ti); t = std::max(t, ti); 14 cnt[ti]++; sum[ti] += ti; 15 } 16 for (int i = 1; i < t + m; i++) { cnt[i] += cnt[i - 1]; sum[i] += sum[i - 1]; } // 前缀和. 17 for (int i = 0; i < t + m; i++) { 18 if (i - m >= 0) { 19 while (l < r && getSlope(q[r - 1], q[r]) >= getSlope(q[r], i - m)) { r--; } 20 q[++r] = i - m; // 把可能成为最优解的推入队列. 21 } 22 while (l < r && getSlope(q[l], q[l + 1]) <= i) { l++; } // 把不可能成为最优解的弹出队列. 23 f[i] = cnt[i] * i - sum[i]; // 特判边界情况. 24 if (l <= r) { f[i] = std::min(f[i], f[q[l]] + (cnt[i] - cnt[q[l]]) * i - (sum[i] - sum[q[l]])); } // 斜率优化转移. 25 } 26 for (int i = t; i < t + m; i++) { ans = std::min(ans, f[i]); } 27 printf("%d ", ans); 28 return 0; 29 }
(实际上还有更优做法,不过并没有研究)
T4:对称二叉树
先讲个笑话:20 -> 0是什么体验?
考场上大暴力都能得分,我写了一遍
然后交了cout << 1;
这题就是典型的:暴力出奇迹
一个dfs就可以过掉的无脑题目,考场上明显把它想难了。
AC代码:
1 #include <cstdio> 2 #include <cctype> 3 #define MAXN 1000010 4 5 int tree[MAXN][2],ans[MAXN],final,val[MAXN]; 6 7 inline int max(int a,int b) { 8 if (a > b) { 9 return a; 10 } 11 else { 12 return b; 13 } 14 } 15 inline int read() { 16 int a = 0,f = 1; 17 char v = getchar(); 18 while (!isdigit(v)) { 19 if (v == '-') { 20 f = -1; 21 } 22 v = getchar(); 23 } 24 while (isdigit(v)) { 25 a = a * 10 + v - 48; 26 v = getchar(); 27 } 28 return a * f; 29 } 30 31 inline void dfs(int u) { 32 ans[u] = 1; 33 if (tree[u][0] != -1) { 34 dfs(tree[u][0]); 35 ans[u] += ans[tree[u][0]]; 36 } 37 if (tree[u][1] != -1) { 38 dfs(tree[u][1]); 39 ans[u] += ans[tree[u][1]]; 40 } 41 } 42 43 inline bool check(int u,int v) { 44 if (u == -1 && v == -1) { 45 return true; 46 } 47 if (u != -1 && v != -1 && val[u] == val[v] && check(tree[u][0],tree[v][1]) && check(tree[u][1],tree[v][0])) { 48 return true; 49 } 50 return false; 51 } 52 53 int main() { 54 int n = read(); 55 for (int i = 1;i <= n;i++) { 56 val[i] = read(); 57 } 58 for (int i = 1;i <= n;i++) { 59 tree[i][0] = read(); 60 tree[i][1] = read(); 61 } 62 dfs(1); 63 for (int i = 1;i <= n;i++) { 64 if (check(tree[i][0],tree[i][1])) { 65 final = max(final,ans[i]); 66 } 67 } 68 printf("%d",final); 69 return 0; 70 }
Part2:期末考
关于这部分,我想了很久。
不能全部怪在考试前突然的感冒,更应该归在最后一两个月的学习状态上。
1月份开始,我似乎就找不到非常好的学习状态,
每一天的学习状态并不是很好,
总是想要努力,但是却没有找到好的方法。
望着自己与别人的差距,有时会狠下心来认真,但大部分的时间里还是不够。
考完几个认为自己能发挥好的学科都考得不怎么样,心态从第一天语文考完就开始爆炸
语文考完:完了,接下来期末考都考不好了
带着这种心态考完了三天,每天都在数着日子
回家之后决定抛弃这种状态,努力学习。
寒假是赶超的最好机会。
我一直记着这句话
今年的寒假,我要改变!
为自己的学习,竞赛加油。
你好,2019.
2019.2.2