正睿20秋季普转提day4
估分:100+100+0+100=300
实际:15+80+0+90=195
T1:
代码写炸了,不会写暴力,没拍
就拓扑排序,优先队列存一下点的编号就行了
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<queue> 5 #include<iostream> 6 #include<algorithm> 7 using namespace std; 8 9 const int N = 100010; 10 11 int n, m, p; 12 int deg[N], top[N]; 13 vector<int> e[N]; 14 priority_queue<int> que; 15 16 void init() 17 { 18 for (int i = 1; i <= n; i++) 19 { 20 e[i].clear(); 21 deg[i] = 0; 22 } 23 } 24 25 int main() 26 { 27 int T; 28 scanf("%d", &T); 29 while (T--) 30 { 31 scanf("%d%d", &n, &m); 32 n = abs(n); 33 34 init(); 35 36 for (int i = 1, x, y; i <= m; i++) 37 { 38 scanf("%d%d", &x, &y); 39 e[y].push_back(x); 40 deg[x]++; 41 } 42 43 for (int i = 1; i <= n; i++) if (!deg[i]) que.push(i); 44 for (p = 0; !que.empty();) 45 { 46 int x = que.top(); 47 que.pop(); 48 top[++p] = x; 49 for (int y : e[x]) 50 { 51 if (!--deg[y]) 52 { 53 que.push(y); 54 } 55 } 56 } 57 58 if (p < n) printf("Impossible!"); 59 else for (; n;) printf("%d ", top[n--]); 60 puts(""); 61 } 62 }
T2:
常数大了+没开longlong=最后两个点没了
每个a改变一位存进哈希表,每个b改变一位查询一次,再把a=b的情况减掉即可
1 #include<cstdio> 2 #include<cstring> 3 #include <map> 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, m; 13 int a[N], b[N]; 14 int A[N * 30], B[N * 30], cnta, cntb; 15 map <int, int> st; 16 17 int main() 18 { 19 scanf("%d%d", &n, &m); 20 for (int i = 1; i <= n; i++) scanf("%d", &a[i]); 21 for (int i = 1; i <= m; i++) scanf("%d", &b[i]); 22 23 for (int i = 1; i <= n; i++) 24 { 25 for (int j = 0; j < 30; j++) 26 { 27 A[++cnta] = a[i] ^ (1 << j); 28 } 29 } 30 for (int i = 1; i <= m; i++) 31 { 32 for (int j = 0; j < 30; j++) 33 { 34 B[++cntb] = b[i] ^ (1 << j); 35 } 36 } 37 38 sort(A + 1, A + cnta + 1); 39 sort(B + 1, B + cntb + 1); 40 41 LL ans = 0; 42 int id1 = 1, id2 = 1; 43 for (int i = 1; i <= cnta; i++) 44 { 45 while (id1 <= cntb && B[id1] < A[i]) ++id1; 46 while (id2 <= cntb && B[id2] <= A[i]) ++id2; 47 if (B[id1] == A[i]) ans += id2 - id1; 48 } 49 for (int i = 1; i <= n; i++) ++st[a[i]]; 50 for (int i = 1; i <= m; i++) ans -= st[b[i]] * 30; 51 cout << ans / 2; 52 }
T3:
不会
T4:
暑假联赛班day5原题,写的时候出了点问题,丢了10分
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 const int N = 100010; 8 9 int n, m; 10 int a[N], b[N], c[N]; 11 int f[2][N], q[N]; 12 13 int main() 14 { 15 int T; 16 scanf("%d", &T); 17 while (T--) 18 { 19 scanf("%d%d", &n, &m); 20 if (m < 0) { puts("1"); continue; } 21 22 for (int i = 1; i <= n; ++i) scanf("%d", &a[i]); 23 for (int i = 1; i <= n; ++i) scanf("%d", &b[i]); 24 for (int i = 1; i <= n; ++i) scanf("%d", &c[i]); 25 26 for (int j = 1; j <= m; ++j) f[0][j] = 2e9 + 1; f[0][0] = 0; 27 28 int x, y, l, r; 29 for (int i = 1; i <= n; ++i) 30 { 31 x = i & 1, y = x ^ 1, l = 1, r = 0; 32 for (int j = 0; j <= m; j++) f[x][j] = f[y][j]; 33 for (int j = a[i]; j <= m; ++j) 34 { 35 while (l <= r && q[l] < j - b[i]) ++l; 36 while (l <= r && f[y][q[r]] >= f[y][j - a[i]]) --r; 37 q[++r] = j - a[i]; 38 f[x][j] = min(f[x][j], f[y][q[l]] + c[i]); 39 } 40 } 41 if (f[x][m] <= 2e9) printf("%d\n", f[x][m]); 42 else puts("IMPOSSIBLE!!!"); 43 } 44 return 0; 45 }
总结:
代码还是容易写炸,暴力的写法得多写;常数的问题也要多注意,之后再看看常数优化,感觉我常数优化要么几乎没变要么负优化。写的时候还得细心点,第三题就代码顺序出了点问题,丢了10分