SMU Autumn 2023 Round 4(Div.1+2)
SMU Autumn 2023 Round 4(Div.1+2)
A. Access Denied
通过分析样例可以得知如果所猜字符串与答案字符串长度不同,则只要\(5ms\),且答案最多\(20\)个字符,因此我们可以先猜20次去核对总字符串长度,如果核对过程中直接猜中了,那就不用继续猜了,又继续分析样例可以得知每遍历一个字符需要消耗\(9ms\),那我们可以对每一位答案的字母一位位地去猜,最多猜\(62\)次,然后最终确定答案字符串,我们在构造初始字符串的时候必须是\(62\)个字符以内的,且又因为构造的是\(62\)位字母内的,所以不排除答案的某些位和我们构造的初始字符串是一样的,导致我们去一位位猜测的时候会刚好有初始的某些位和答案的一样,所以程序就会继续跑,最后返回的结果不是比上一次猜测刚好多\(9ms\),而是更多
#include <bits/stdc++.h> using namespace std; using i64 = long long; typedef pair<i64, i64> PII; char ans[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; int main() { int t = 0; string s, now; for (int i = 1; i <= 20; i ++) { t = 0; s = string(i, '0'); cout << s << endl; getline(cin, now); if (now == "ACCESS GRANTED") exit(0); for (auto j : now) if (isdigit(j)) t = t * 10 + (j - '0'); if (t != 5) { t = i; break; } } string res = string(t, '0'); int T; for (int i = 0; i < t; i ++) { for (int j = 0; j < 62; j ++) { T = 0; res[i] = ans[j]; cout << res << endl; getline(cin, now); if (now == "ACCESS GRANTED") exit(0); for (auto k : now) if (isdigit(k)) T = T * 10 + (k - '0'); if (T >= 5 + (i + 2) * 9) break; } } return 0; }
J. Jet Set
由题目可知,极点经过了所有经线,且经过所有经线就认为是环游了世界,所以对于两个地点,如果它们的经度刚好相差180,那么这两点走经过经线的那段圆弧即是最短的,也就一定环游了世界,对于其余的点,我们只要看它们两者经度差与180比较,大于180的,说明走反着走更短,否则就正着走更短,且数据较小,我们可以直接循环去标记他经过哪些经线即可
#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; cin >> n; vector<int> Wei(n + 1); for(int i = 0;i < n;i ++){ int x; cin >> x >> Wei[i]; Wei[i] += 180; } Wei[n] = Wei[0]; vector<bool> vis(996,false); for(int i = 1;i <= n;i ++){ if(abs(Wei[i] - Wei[i - 1]) == 180){ cout << "yes\n"; return 0; }else if(abs(Wei[i] - Wei[i - 1]) > 180){ for(int j = 0;j <= min(Wei[i],Wei[i - 1]) * 2;j ++){ vis[j] = true; } for(int j = max(Wei[i], Wei[i - 1]) * 2;j <= 720;j ++){ vis[j] = true; } }else{ for(int j = min(Wei[i], Wei[i - 1]) * 2;j <= max(Wei[i], Wei[i - 1]) * 2;j ++) vis[j] = true; } } for(int i = 0;i <= 720;i ++){ if(!vis[i]){ printf("no %.1lf\n", (double)i / 2 - 180); return 0; } } cout << "yes\n"; return 0; }
K. Knitpicking
题意就是给你一堆混合在一起的袜子,问你最少拿多少只袜子能够配队,\(left\)和\(right\)是分开配对,\(any\)则左右皆可,对于同一类型的袜子,最坏情况下肯定是拿到左右袜子中数量最多的那一堆,对于某类只有\(any\)类型的,我们只需拿\(1\)只即可,把这些加起来,最后随便再拿一只都能完成配对
#include <bits/stdc++.h> using namespace std; using i64 = long long; typedef pair<i64, i64> PII; map<string,array<int,3>> cs; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; bool match = false; for(int i = 0;i < n;i ++){ string s1,s2; int k; cin >> s1 >> s2 >> k; if(s2 == "left") cs[s1][0] = k; else if(s2 == "right") cs[s1][1] = k; else cs[s1][2] = k; if(s2 == "any" && k > 1) match = true; else if(s2 == "left" && cs[s1][1]) match = true; else if(s2 == "right" && cs[s1][0]) match = true; } if(!match){ cout << "impossible\n"; }else{ int ans = 0; for(auto [x,y] : cs){ if(!y[0] && !y[1]) ans ++; else ans += max(y[0], y[1]); } cout << ans + 1 << '\n'; } return 0; }
本文作者:Ke_scholar
本文链接:https://www.cnblogs.com/Kescholar/p/17710440.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步