SMU Autumn 2023 Round 2(Div.1+2)
SMU Autumn 2023 Round 2(Div.1+2)
C. Chaotic Construction
把环展开的话就是\(1 \sim 2n\),若\(D\)的位置放上路障的话,在这个展开的环上就是\(D\)和\(D+n\)的位置,对于\(x,y\),我们就是去看\(D\)或者\(D+n\)是否处于\(x,y\)中间的位置,可以设置一个\(ans = 0\)表示最开始无路障时都能走通,然后对存进\(set\)里的路障二分找到\(x,y\)和\(y,x+n\)中间是否存在路标,若存在,则\(ans+1\),当\(ans = 2\)时说明无论向前还是向后都走不通
#include <bits/stdc++.h> #define debug(a) cout<<#a<<"="<<a<<'\n'; using namespace std; using i64 = long long; typedef pair<i64, i64> PII; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, q; map<int, int> f; cin >> n >> q; set<i64> road; road.insert(0); for (int i = 0; i < q; i ++) { char op; int x, y; cin >> op >> x; if (op == '?') { cin >> y; if (x > y) swap(x, y); if (f[x] || f[y]) { cout << "impossible\n"; continue; } int ans = 0; auto p = *road.lower_bound(x),q = *road.lower_bound(y); if(p != q) ans ++ ; auto pq = *road.lower_bound(x + n); if(pq != q) ans ++; cout << (ans > 1 ? "impossible\n" : "possible\n"); } else { if (op == '-') { f[x] = 1; road.insert(x), road.insert(x + n); } else { f[x] = 0; road.erase(x), road.erase(x + n); } } } return 0; }
D. Diabolic Doofenshmirtz
\(1e12\)不会超过\(2^{42}\),所以询问的时候可以倍增地去问,每次记录上一次回答的长度,如果当某次的\(x\)小于了之前记录的长度,说明这个时候刚好已经跑过一圈了,而这个时候的\(x\)是跑了一圈之后的位置,\(now\)是现在跑了的路程,那么\(now - x\)即为一圈的长度了
#include <bits/stdc++.h> #define debug(a) cout<<#a<<"="<<a<<'\n'; using namespace std; using i64 = long long; typedef pair<i64, i64> PII; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); i64 now = 1, last = 0; for(int i = 1;i <= 42;i ++){ cout << "? " << now << endl; i64 x; cin >> x; if(x <= last){ cout << "! " << now - x << endl; break; } last = x; now *= 2; } return 0; }
E. Enjoyable Entree
规律题,如果你打表的话就会发现当\(n\)超过\(30\)之后,两个比例都会趋近一个极限\(33.333333\)和\(66.666667\),想到了这点就容易做了
#include <bits/stdc++.h> #define debug(a) cout<<#a<<"="<<a<<'\n'; using namespace std; using i64 = long long; typedef pair<i64, i64> PII; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); i64 n; cin >> n; if(n == 1){ cout << "100 0\n"; }else if(n == 2){ cout << "0 100\n"; }else{ if(n > 30){ cout << "33.333333 66.666667\n"; }else{ double ans = 50, a = 50,b = 25; for(int i = 5;i <= n;i ++){ ans = a / 2 + b / 2; a = b; b = ans; } if(n == 3) cout << "50 50\n"; else if(n == 4) cout << "25 75\n"; else printf("%.6lf %.6lf\n",ans, 100 - ans); } } return 0; }
I. Improving IT
\(f[i]\)表示第\(i\)个月赚了多少钱,首先最开始\(dp[1]=0\)表示没有买\(CPU\)时的初值,此后每个月都减掉\(a\)表示新买一个\(CPU\)所花掉的钱,\(dp[i+j]=max(dp[i+j],dp[i]+b)\)则代表第\(i+j\)个月以\(b\)价格卖出第\(i\)月买的\(CPU\)是否会赚的更多
#include <bits/stdc++.h> #define debug(a) cout<<#a<<"="<<a<<'\n'; using namespace std; using i64 = long long; typedef pair<i64, i64> PII; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n,m; cin >> n >> m; vector<i64> f(n + 2,-LLONG_MAX); f[1] = 0; for(int i = 1;i <= n;i ++){ int a; cin >> a; f[i] -= a; for(int j = 1;j <= min(m, n - i + 1);j ++){ int b; cin >> b; f[i + j] = max(f[i + j], f[i] + b); } } cout << -f[n + 1] << '\n'; return 0; }
K. K.O. Kids
当\(f=1\)时应该迈左脚,\(f=0\)时迈右脚,否则的话就丢掉一个人,正常模拟即可
#include <bits/stdc++.h> #define debug(a) cout<<#a<<"="<<a<<'\n'; using namespace std; using i64 = long long; typedef pair<i64, i64> PII; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n,k; string s; cin >> n >> k >> s; bool f = 1; int ans = k; for(int i = 0;i < n;i ++){ if(f && s[i] != 'L') ans --; else if(!f && s[i] != 'R') ans --; else f ^= 1; } cout << max(0, ans) << '\n'; return 0; }
L. Lots of Land
当整个矩形的面积不能整除\(n\)时说明不能划分成\(n\)个面积相等的矩形,,否则的话就取\(k = \frac{S}{n}\),则每个小矩形的面积就等于\(k\),则让\(k\)与边或宽取个最大公约数就能计算出小矩形的长和宽,然后就是正常模拟
#include <bits/stdc++.h> #define debug(a) cout<<#a<<"="<<a<<'\n'; using namespace std; using i64 = long long; typedef pair<i64, i64> PII; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int l,w,n; cin >> l >> w >> n; vector<string> g(l, string(w, 'A')); if((l * w) % n != 0){ cout << "IMPOSSIBLE\n" ; }else{ int k = l * w / n; char op = 'A'; int L = gcd(k, l), W = k / L; for(int i = 0;i < l;i ++){ int p = 0; for(int j = 0;j < w;j ++){ if(j && j % W == 0) p++; g[i][j] = op + p; } if((i + 1) % L == 0) op = op + p + 1; } for(auto i : g) cout << i << '\n'; } return 0; }
本文作者:Ke_scholar
本文链接:https://www.cnblogs.com/Kescholar/p/17692322.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步