第一场多校就打的这么惨,只能说自己太菜了,还需继续努力啊~
题目链接:
GYM链接:https://codeforces.com/gym/101933
CSU链接:http://acm.csu.edu.cn:20080/csuoj/contest/problemset?cid=2178
A题:
题意:
有n只青蛙掉到了井里,然后可以靠叠罗汉和向上跳逃离水井,每只青蛙有三个属性分别为跳高值,体重(承重能力),身高,问最多能有多少只青蛙能够逃离水井。
思路:
因为每只青蛙的承重能力是有限的,因此我们按照承重能力从大到小排序,然后进行背包,dp[i]表示体重为i最多能达到多高,转移方程为dp[i]=max(dp[i], dp[i+w]+h)。
代码实现如下:
1 #include <set> 2 #include <map> 3 #include <deque> 4 #include <queue> 5 #include <stack> 6 #include <cmath> 7 #include <ctime> 8 #include <bitset> 9 #include <cstdio> 10 #include <string> 11 #include <vector> 12 #include <cstdlib> 13 #include <cstring> 14 #include <iostream> 15 #include <algorithm> 16 #include <bits/stdc++.h> 17 using namespace std; 18 19 typedef long long LL; 20 typedef pair<LL, LL> pLL; 21 typedef pair<LL, int> pLi; 22 typedef pair<int, LL> piL;; 23 typedef pair<int, int> pii; 24 typedef unsigned long long uLL; 25 26 #define lson rt<<1 27 #define rson rt<<1|1 28 #define lowbit(x) x&(-x) 29 #define name2str(name) (#name) 30 #define bug printf("********* ") 31 #define debug(x) cout<<#x"=["<<x<<"]" <<endl 32 #define FIN freopen("in","r",stdin) 33 #define IO ios::sync_with_stdio(false),cin.tie(0) 34 35 const double eps = 1e-8; 36 const int mod = 1e9 + 7; 37 const int maxn = 1e5 + 7; 38 const double pi = acos(-1); 39 const int inf = 0x3f3f3f3f; 40 const LL INF = 0x3f3f3f3f3f3f3f3fLL; 41 42 int n, d; 43 int dp[100000007]; 44 45 struct node { 46 int l, w, h; 47 bool operator < (const node& x) const { 48 return w > x.w; 49 } 50 }pp[maxn]; 51 52 int main() { 53 scanf("%d%d", &n, &d); 54 for(int i = 1; i <= n; ++i) { 55 scanf("%d%d%d", &pp[i].l, &pp[i].w, &pp[i].h); 56 } 57 sort(pp + 1, pp + n + 1); 58 int ans = 0; 59 for(int i = 1; i <= n; ++i) { 60 int w = pp[i].w; 61 for(int j = 1; j < w && (j + w) <= 1e8; ++j) { 62 dp[j] = min(d + 2, max(dp[j], dp[j+w] + pp[i].h)); 63 } 64 if(dp[w] + pp[i].l > d) ++ans; 65 } 66 printf("%d ", ans); 67 return 0; 68 }
B题:
题意:
给你n个数字或者字符串,问你是否能够把它还原成1~n。
思路:
直接On遍历即可。
代码实现如下:
1 #include <set> 2 #include <map> 3 #include <deque> 4 #include <queue> 5 #include <stack> 6 #include <cmath> 7 #include <ctime> 8 #include <bitset> 9 #include <cstdio> 10 #include <string> 11 #include <vector> 12 #include <cstdlib> 13 #include <cstring> 14 #include <iostream> 15 #include <algorithm> 16 #include <bits/stdc++.h> 17 using namespace std; 18 19 typedef long long LL; 20 typedef pair<LL, LL> pLL; 21 typedef pair<LL, int> pLi; 22 typedef pair<int, LL> piL;; 23 typedef pair<int, int> pii; 24 typedef unsigned long long uLL; 25 26 #define lson rt<<1 27 #define rson rt<<1|1 28 #define lowbit(x) x&(-x) 29 #define name2str(name) (#name) 30 #define bug printf("********* ") 31 #define debug(x) cout<<#x"=["<<x<<"]" <<endl 32 #define FIN freopen("in","r",stdin) 33 #define IO ios::sync_with_stdio(false),cin.tie(0) 34 35 const double eps = 1e-8; 36 const int mod = 1e9 + 7; 37 const int maxn = 1e6 + 7; 38 const double pi = acos(-1); 39 const int inf = 0x3f3f3f3f; 40 const LL INF = 0x3f3f3f3f3f3f3f3fLL; 41 42 int n; 43 char s[15]; 44 45 int main() { 46 int flag = 1; 47 scanf("%d", &n); 48 for(int i = 1; i <= n; i++) { 49 scanf("%s", s); 50 if(s[0] == 'm') continue; 51 int len = strlen(s); 52 int num = 0; 53 for(int j = 0; j < len; j++) { 54 num = num * 10 + s[j] - '0'; 55 } 56 if(num != i) flag = 0; 57 } 58 if(flag) puts("makes sense"); 59 else puts("something is fishy"); 60 return 0; 61 }
C题:
题意:
给定n天产生垃圾,第i天垃圾的累积量为,如果累积量在j+1天会大于等于20,则需在前一天打扫卫生,问至少需要打扫多少次卫生。
思路:
枚举天数,然后与前面没被清理的垃圾进行累计求和,如果大于等于20则将前面的垃圾清空。
代码实现如下:
1 #include <set> 2 #include <map> 3 #include <deque> 4 #include <queue> 5 #include <stack> 6 #include <cmath> 7 #include <ctime> 8 #include <bitset> 9 #include <cstdio> 10 #include <string> 11 #include <vector> 12 #include <cstdlib> 13 #include <cstring> 14 #include <iostream> 15 #include <algorithm> 16 #include <bits/stdc++.h> 17 using namespace std; 18 19 typedef long long LL; 20 typedef pair<LL, LL> pLL; 21 typedef pair<LL, int> pLi; 22 typedef pair<int, LL> piL;; 23 typedef pair<int, int> pii; 24 typedef unsigned long long uLL; 25 26 #define lson rt<<1 27 #define rson rt<<1|1 28 #define lowbit(x) x&(-x) 29 #define name2str(name) (#name) 30 #define bug printf("********* ") 31 #define debug(x) cout<<#x"=["<<x<<"]" <<endl 32 #define FIN freopen("in","r",stdin) 33 #define IO ios::sync_with_stdio(false),cin.tie(0) 34 35 const double eps = 1e-8; 36 const int mod = 1e9 + 7; 37 const int maxn = 400 + 7; 38 const double pi = acos(-1); 39 const int inf = 0x3f3f3f3f; 40 const LL INF = 0x3f3f3f3f3f3f3f3fLL; 41 42 int n; 43 int a[maxn], vis[maxn]; 44 45 int main() { 46 scanf("%d", &n); 47 for(int i = 1; i <= n; i++) { 48 scanf("%d", &a[i]); 49 } 50 int ans = 0; 51 for(int i = 1; i <= 385; i++) { 52 int sum = 0; 53 for(int j = 1; j <= n; j++) { 54 if(a[j] > i) break; 55 if(vis[a[j]]) continue; 56 sum += i - a[j]; 57 if(sum >= 20) { 58 ans++; 59 sum = 0; 60 for(int k = 1; k < i; k++) vis[k] = 1; 61 break; 62 } 63 } 64 } 65 printf("%d ", ans); 66 return 0; 67 }
D题:
题意:
有一家披萨店要配送披萨,给定一张有n个结点的图和m条有边权的边,有q份订单,每份订单给定下单时间,终点,制作这份披萨结束的时间,问你这q份订单中要等待的最长时间的最小值(注意一次可以配送多份订单,但需要按照下单时间来,下单时间和制作完成时间单调递增)。
思路:
因为一次可以拿多份披萨进行配送且必须按照顺序配送,因此我们先跑n遍dijstra求出任意两点间的最短路。
二分需要等待的最长时间的最小值x,然后check进行dp,dp[u]表示配送完u这份订单且回到起点(1)的最短时间,由于q不大,因此我们可以枚举分界点进行分段,总复杂度为O(nmlog(n)+35q2)。
代码实现如下:
1 #include <set> 2 #include <map> 3 #include <deque> 4 #include <queue> 5 #include <stack> 6 #include <cmath> 7 #include <ctime> 8 #include <bitset> 9 #include <cstdio> 10 #include <string> 11 #include <vector> 12 #include <cstdlib> 13 #include <cstring> 14 #include <iostream> 15 #include <algorithm> 16 #include <bits/stdc++.h> 17 using namespace std; 18 19 typedef long long LL; 20 typedef pair<LL, LL> pLL; 21 typedef pair<LL, int> pLi; 22 typedef pair<int, LL> piL;; 23 typedef pair<int, int> pii; 24 typedef unsigned long long uLL; 25 26 #define lson rt<<1 27 #define rson rt<<1|1 28 #define lowbit(x) x&(-x) 29 #define name2str(name) (#name) 30 #define bug printf("********* ") 31 #define debug(x) cout<<#x"=["<<x<<"]" <<endl 32 #define FIN freopen("in","r",stdin) 33 #define IO ios::sync_with_stdio(false),cin.tie(0) 34 35 const double eps = 1e-8; 36 const int mod = 1e9 + 7; 37 const int maxn = 1e3 + 7; 38 const double pi = acos(-1); 39 const int inf = 0x3f3f3f3f; 40 const LL INF = 0x3f3f3f3f3f3f3f3fLL; 41 42 int n, m, q, tot, u, v, w; 43 int head[maxn], vis[maxn]; 44 LL dis[maxn][maxn], dp[maxn]; 45 46 struct edge { 47 int v, w, next; 48 }ed[maxn*10]; 49 50 struct node { 51 int s, t, u; 52 }num[maxn]; 53 54 void add(int u, int v, int w) { 55 ed[tot].v = v; 56 ed[tot].w = w; 57 ed[tot].next = head[u]; 58 head[u] = tot++; 59 } 60 61 void dij(int s) { 62 priority_queue<pLi, vector<pLi>, greater<pLi> > q; 63 for(int i = 1; i <= n; ++i) { 64 vis[i] = 0; 65 dis[s][i] = INF; 66 } 67 dis[s][s] = 0; 68 q.push({0, s}); 69 int u, v; 70 while(!q.empty()) { 71 u = q.top().second; q.pop(); 72 if(vis[u]) continue; 73 vis[u] = 1; 74 for(int i = head[u]; ~i; i = ed[i].next) { 75 v = ed[i].v; 76 if(dis[s][v] > dis[s][u] + ed[i].w) { 77 dis[s][v] = dis[s][u] + ed[i].w; 78 q.push({dis[s][v], v}); 79 } 80 } 81 } 82 } 83 84 bool check(LL x) { 85 for(int i = 1; i <= q; ++i) dp[i] = INF; 86 for(int i = 0; i < q; ++i) { 87 LL tmp = 0, las = dp[i], pp = INF; 88 for(int j = 1; i + j <= q; ++j) { 89 int v = i + j; 90 if(j == 1) tmp += dis[1][num[v].u]; 91 else tmp += dis[num[v-1].u][num[v].u]; 92 las = max(dp[i], 1LL * num[v].t); 93 if(las + tmp - num[v].s > x) break; 94 pp = min(pp, x + num[v].s - tmp); 95 if(pp < las) break; 96 dp[v] = min(dp[v], las + tmp + dis[num[v].u][1]); 97 } 98 } 99 return dp[q] < INF; 100 } 101 102 int main() { 103 scanf("%d%d", &n, &m); 104 for(int i = 1; i <= n; ++i) { 105 head[i] = -1; 106 } 107 for(int i = 1; i <= m; ++i) { 108 scanf("%d%d%d", &u, &v, &w); 109 add(u, v, w), add(v, u, w); 110 } 111 for(int i = 1; i <= n; ++i) dij(i); 112 scanf("%d", &q); 113 for(int i = 1; i <= q; ++i) { 114 scanf("%d%d%d", &num[i].s, &num[i].u, &num[i].t); 115 } 116 LL ub = 1e15, lb = 0, mid, ans = 0; 117 while(ub >= lb) { 118 mid = (ub + lb) >> 1; 119 if(check(mid)) { 120 ub = mid - 1; 121 ans = mid; 122 } else { 123 lb = mid + 1; 124 } 125 } 126 printf("%lld ", ans); 127 return 0; 128 }
E题:
题意:
己方有n个小兵,敌方有m个小兵,每个小兵的血量给定,现在总共有d点伤害,d点伤害会一点一点地对场上所有活着的小兵中的某一个造成一点伤害(包括己方),每个小兵收到这点伤害的概率相等,问敌方小兵全死的概率。
思路:
有两种方法,一种是用十进制记录每个小兵现在还剩多少的血量,另一种是记录剩余血量为i的小兵有多少个,然后进行记忆化搜索,貌似第二种方法快一点。
代码实现如下:
第一种方法:
1 #include <set> 2 #include <map> 3 #include <deque> 4 #include <queue> 5 #include <stack> 6 #include <cmath> 7 #include <ctime> 8 #include <bitset> 9 #include <cstdio> 10 #include <string> 11 #include <vector> 12 #include <cstdlib> 13 #include <cstring> 14 #include <iostream> 15 #include <algorithm> 16 #include <bits/stdc++.h> 17 using namespace std; 18 19 typedef long long LL; 20 typedef pair<LL, LL> pLL; 21 typedef pair<LL, int> pLi; 22 typedef pair<int, LL> piL;; 23 typedef pair<int, int> pii; 24 typedef unsigned long long uLL; 25 26 #define lson rt<<1 27 #define rson rt<<1|1 28 #define lowbit(x) x&(-x) 29 #define name2str(name) (#name) 30 #define bug printf("********* ") 31 #define debug(x) cout<<#x"=["<<x<<"]" <<endl 32 #define FIN freopen("in","r",stdin) 33 #define IO ios::sync_with_stdio(false),cin.tie(0) 34 35 const double eps = 1e-8; 36 const int mod = 1e9 + 7; 37 const int maxn = 1e6 + 7; 38 const double pi = acos(-1); 39 const int inf = 0x3f3f3f3f; 40 const LL INF = 0x3f3f3f3f3f3f3f3fLL; 41 42 int n, m, d, cnt, sum; 43 int a[15], b[15], c[15]; 44 LL pw[15]; 45 LL las; 46 unordered_map<LL, double> dp; 47 48 void update(LL& x) { 49 cnt = 0; 50 for(int i = n; i > 0; --i) a[i] = x % 10, x /= 10; 51 for(int i = m; i > 0; --i) b[i] = x % 10, x /= 10; 52 sort(a + 1, a + n + 1); 53 sort(b + 1, b + m + 1); 54 for(int i = 1; i <= m; ++i) x = x * 10 + b[i]; 55 for(int i = 1; i <= n; ++i) x = x * 10 + a[i]; 56 for(int i = 1; i <= n; ++i) { 57 c[n+1-i] = a[i]; 58 if(a[i] > 0) cnt++; 59 } 60 for(int i = 1; i <= m; ++i) { 61 c[n+m+1-i] = b[i]; 62 if(b[i] > 0) cnt++; 63 } 64 } 65 66 double dfs(LL nw, int d) { 67 update(nw); 68 int p[15]; 69 int num = cnt; 70 if(dp.find(nw) != dp.end()) return dp[nw]; 71 if(nw < las) return dp[nw] = 1.000000; 72 if(d == 0) return dp[nw] = 0.000000; 73 double tmp = 0; 74 for(int i = 1; i <= n + m; ++i) p[i] = c[i]; 75 for(int i = 1; i <= n + m; ++i) { 76 if(p[i] == 0) continue; 77 --p[i]; 78 if(p[i] == 0) num--; 79 tmp += dfs(nw - pw[i], d - 1) / (num + (p[i] == 0)); 80 if(p[i] == 0) num++; 81 ++p[i]; 82 } 83 return dp[nw] = tmp; 84 } 85 86 int main() { 87 scanf("%d%d%d", &n, &m, &d); 88 for(int i = 1; i <= n; ++i) scanf("%d", &a[i]), sum += a[i]; 89 for(int i = 1; i <= m; ++i) scanf("%d", &b[i]), sum += b[i]; 90 if(d >= sum) return printf("1.000000 ") * 0; 91 LL nw = 0; 92 las = 1; 93 cnt = n + m; 94 for(int i = 1; i <= m; ++i) nw = nw * 10 + b[i], c[n+m+1-i] = b[i]; 95 for(int i = 1; i <= n; ++i) nw = nw * 10 + a[i], las = las * 10, c[n+1-i] = a[i]; 96 pw[1] = 1; 97 for(int i = 2; i <= n + m; ++i) pw[i] = pw[i-1] * 10; 98 printf("%.7f ", dfs(nw, d)); 99 return 0; 100 }
第二种方法:
1 #include <set> 2 #include <map> 3 #include <deque> 4 #include <queue> 5 #include <stack> 6 #include <cmath> 7 #include <ctime> 8 #include <bitset> 9 #include <cstdio> 10 #include <string> 11 #include <vector> 12 #include <cstdlib> 13 #include <cstring> 14 #include <iostream> 15 #include <algorithm> 16 #include <bits/stdc++.h> 17 using namespace std; 18 19 typedef long long LL; 20 typedef pair<LL, LL> pLL; 21 typedef pair<LL, int> pLi; 22 typedef pair<int, LL> piL;; 23 typedef pair<int, int> pii; 24 typedef unsigned long long uLL; 25 26 #define lson rt<<1 27 #define rson rt<<1|1 28 #define lowbit(x) x&(-x) 29 #define name2str(name) (#name) 30 #define bug printf("********* ") 31 #define debug(x) cout<<#x"=["<<x<<"]" <<endl 32 #define FIN freopen("in","r",stdin) 33 #define IO ios::sync_with_stdio(false),cin.tie(0) 34 35 const double eps = 1e-8; 36 const int mod = 1e9 + 7; 37 const int maxn = 1e6 + 7; 38 const double pi = acos(-1); 39 const int inf = 0x3f3f3f3f; 40 const LL INF = 0x3f3f3f3f3f3f3f3fLL; 41 42 int n, m, d; 43 LL pw[15]; 44 unordered_map<LL, double> dp; 45 int a[7], b[7]; 46 47 double dfs(LL nw, int d) { 48 if(dp.find(nw) != dp.end()) return dp[nw]; 49 if(nw < pw[7]) return dp[nw] = 1.0; 50 if(d == 0) return dp[nw] = 0.0; 51 double tmp = 0; 52 int num = 0; 53 LL pp = nw; 54 for(int j = 1; j <= 12; ++j) { 55 num += pp % 10; 56 pp /= 10; 57 } 58 for(int i = 1; i <= 12; ++i) { 59 int x = (nw % pw[i+1]) / pw[i]; 60 if(x == 0) continue; 61 nw -= pw[i]; 62 if(i != 7 && i != 1) nw += pw[i-1]; 63 tmp += x * dfs(nw, d - 1) / num; 64 nw += pw[i]; 65 if(i != 7 && i != 1) nw -= pw[i-1]; 66 } 67 return dp[nw] = tmp; 68 } 69 70 int main() { 71 scanf("%d%d%d", &n, &m, &d); 72 int sum = 0; 73 for(int i = 1; i <= n; ++i) scanf("%d", &a[i]), sum += a[i]; 74 for(int i = 1; i <= m; ++i) scanf("%d", &b[i]), sum += b[i]; 75 if(sum <= d) return printf("1.0000000 ") * 0; 76 LL nw = 0; 77 pw[1] = 1; 78 for(int i = 2; i <= 13; ++i) pw[i] = pw[i-1] * 10; 79 for(int i = m; i >= 1; --i) nw += pw[6+b[i]]; 80 for(int i = n; i >= 1; --i) nw += pw[a[i]]; 81 printf("%.7f ", dfs(nw, d)); 82 return 0; 83 }
H题:
题意:
你有一块边长为l的花园,然后有n个修理机器可以考虑,每个修理机器有名字、花费、工作速度、工作时间、充电时间,要你输出开销最小且能保证每周至少修理一次的所有机器的名字。
思路:
我们先按照花费从小到大排序然后计算是否能够保证每周至少修理一次即可。
代码实现如下:
1 #include <set> 2 #include <map> 3 #include <deque> 4 #include <queue> 5 #include <stack> 6 #include <cmath> 7 #include <ctime> 8 #include <bitset> 9 #include <cstdio> 10 #include <string> 11 #include <vector> 12 #include <cstdlib> 13 #include <cstring> 14 #include <iostream> 15 #include <algorithm> 16 #include <bits/stdc++.h> 17 using namespace std; 18 19 typedef long long LL; 20 typedef pair<LL, LL> pLL; 21 typedef pair<LL, int> pLi; 22 typedef pair<int, LL> piL;; 23 typedef pair<int, int> pii; 24 typedef unsigned long long uLL; 25 26 #define lson rt<<1 27 #define rson rt<<1|1 28 #define lowbit(x) x&(-x) 29 #define name2str(name) (#name) 30 #define bug printf("********* ") 31 #define debug(x) cout<<#x"=["<<x<<"]" <<endl 32 #define FIN freopen("in","r",stdin) 33 #define IO ios::sync_with_stdio(false),cin.tie(0) 34 35 const double eps = 1e-8; 36 const int mod = 1e9 + 7; 37 const int maxn = 1e6 + 7; 38 const double pi = acos(-1); 39 const int inf = 0x3f3f3f3f; 40 const LL INF = 0x3f3f3f3f3f3f3f3fLL; 41 42 int l, m; 43 char s[155]; 44 45 struct node { 46 char name[65]; 47 int p, c, t, r, id; 48 bool operator < (const node& x) const { 49 return p == x.p ? id < x.id : p < x.p; 50 } 51 }num[105]; 52 53 int main() { 54 char* p; 55 scanf("%d%d", &l, &m); 56 getchar(); 57 for(int i = 1; i <= m; ++i) { 58 memset(s, '