正睿20秋季普转提day1
估分:100+100+30+30=260
实际:100+0+10+10=120
T1:
正解:简单的模拟
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 typedef long long LL; 8 9 LL read() 10 { 11 LL x = 0, f = 0; 12 char ch = getchar(); 13 while (!isdigit(ch)) f = ch == '-', ch = getchar(); 14 while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar(); 15 return f ? -x : x; 16 } 17 18 void get(LL& x, LL& y, LL dir) 19 { 20 switch(dir) 21 { 22 case 0: 23 break; 24 case 1: 25 x = -x; 26 swap(x, y); 27 break; 28 case 2: 29 x = -1, y = -1; 30 break; 31 case 3: 32 y = -y; 33 swap(x, y); 34 break; 35 } 36 } 37 38 int main() 39 { 40 LL n = read(), T = read(); 41 LL x = 0, y = 0, dir = 0; 42 for (int i = 1; i <= n; i++) 43 { 44 LL a = read(); 45 switch (dir) 46 { 47 case 1: 48 x += a; 49 break; 50 case 2: 51 y += a; 52 break; 53 case 3: 54 x -= a; 55 break; 56 case 0: 57 y -= a; 58 break; 59 } 60 dir += a % 4; 61 dir %= 4; 62 } 63 64 65 LL dx = x, dy = y; 66 x = y = 0; 67 while (T--) 68 { 69 get(dx, dy, dir); 70 x += dx, y += dy; 71 } 72 printf("%lld", abs(x) + abs(y)); 73 }
T2:
错题原因:代码写炸了,思路没问题
正解:枚举在哪停下,再把之前的餐馆能选则选,优先队列优化一下
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 8 typedef long long LL; 9 10 const int N = 100010; 11 12 int n, ans; 13 LL m, sum; 14 int t[N]; 15 16 priority_queue<int> q; 17 18 struct Node 19 { 20 LL x; 21 int t; 22 Node() {} 23 } a[N]; 24 25 inline bool cmp(Node x, Node y) 26 { 27 return x.x < y.x; 28 } 29 30 int main() 31 { 32 scanf("%d%lld", &n, &m); 33 34 for (int i = 1; i <= n; i++) scanf("%lld%d", &a[i].x, &a[i].t); 35 36 sort(a + 1, a + 1 + n, cmp); 37 38 LL last = 0; 39 for (int i = 1; i <= n; i++) 40 { 41 LL x = a[i].x; 42 int t = a[i].t; 43 m -= (x - last); 44 last = x; 45 while (!q.empty() && sum > m) 46 { 47 sum -= q.top(); 48 q.pop(); 49 } 50 if (sum + t <= m) 51 { 52 q.push(t); 53 sum += t; 54 } 55 ans = max(ans, (int)q.size()); 56 } 57 58 printf("%d\n", ans); 59 }
T3:
错题原因:想到了这个DP,但不会证明,没敢写,写了暴力,但是写的暴力思路出了点问题
正解:L当容量,D当价值跑背包
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 const int N = 1010; 8 9 int n; 10 int f[N], l[N], d[N]; 11 12 int main() 13 { 14 scanf("%d", &n); 15 for (int i = 1; i <= n; i++) scanf("%d", &l[i]); 16 for (int i = 1; i <= n; i++) scanf("%d", &d[i]); 17 18 for (int i = 1; i <= n; i++) 19 { 20 for (int j = n; j >= l[i]; j--) 21 { 22 f[j] = max(f[j], f[j - l[i]] + d[i]); 23 } 24 } 25 printf("%d", f[n]); 26 }
T4:
错题原因:思路想到了,但是set还不熟不会用,不知道怎么优化成满分代码,写了个30分暴力,但是爆int了,只得十分
正解:对于每种书用一个权值线段树维护(或set),对于总的再用一个权值线段树维护(或set),没有选的书也要维护一下,RETURN操作时要用,再模拟一下即可
1 #include<cstdio> 2 #include<cstring> 3 #include<set> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 8 const int N = 300010; 9 10 inline int read() 11 { 12 int s = 0; char ch = getchar(); 13 while (ch < '0' || ch>'9') ch = getchar(); 14 while (ch <= '9' && ch >= '0') { s = (s << 1) + (s << 3) + (ch ^ 48); ch = getchar(); } 15 return s; 16 } 17 18 int n, m; 19 long long ans; 20 multiset<int> s1[N], s2[N], f, del; 21 22 inline void add(int x) 23 { 24 if (f.size() < n) 25 { 26 f.insert(x); 27 ans += x; 28 } 29 else 30 { 31 int flag = *f.begin(); 32 if (x > flag) 33 { 34 del.insert(flag); 35 ans -= flag; 36 f.erase(f.begin()); 37 f.insert(x); 38 ans += x; 39 } 40 else del.insert(x); 41 } 42 } 43 44 inline void modify(int x) 45 { 46 if (f.find(x) != f.end()) 47 { 48 ans -= x; 49 f.erase(f.find(x)); 50 if (!del.empty()) 51 { 52 int flag = *del.rbegin(); 53 del.erase(--del.end()); 54 f.insert(flag); 55 ans += flag; 56 } 57 } 58 else del.erase(x); 59 } 60 61 int main() 62 { 63 scanf("%d%d", &n, &m); 64 65 for (int i = 1; i <= m; i++) 66 { 67 char opt[10]; 68 scanf(" %s", opt); 69 int t = read(), x = read(); 70 if (opt[0] == 'B') 71 { 72 if (s1[t].size() < t) 73 { 74 s1[t].insert(x); 75 add(x); 76 } 77 else 78 { 79 int flag = *s1[t].begin(); 80 if (x > flag) 81 { 82 modify(flag); 83 s2[t].insert(flag); 84 s1[t].erase(s1[t].begin()); 85 add(x); 86 s1[t].insert(x); 87 } 88 else s2[t].insert(x); 89 } 90 } 91 else 92 { 93 if (s1[t].find(x) != s1[t].end()) 94 { 95 s1[t].erase(s1[t].find(x)); 96 modify(x); 97 if (!s2[t].empty()) 98 { 99 int flag = *s2[t].rbegin(); 100 s1[t].insert(flag); 101 s2[t].erase(--s2[t].end()); 102 add(flag); 103 } 104 } 105 else s2[t].erase(s2[t].find(x)); 106 } 107 printf("%lld\n", ans); 108 } 109 }
总结:
题目的正解思路都是想到了的,但不是写炸了就是不会写,代码能力还是太差,以前学的一些数据结构忘了,要复习一下,数据结构还要多写,容易写错;题目的数据范围也要注意,注意会不会爆int什么的
浙公网安备 33010602011771号