牛客周赛 Round 61
A-Letter Song
签到题
代码
#include <iostream> using namespace std; int main() { int a, b, c; char x; cin >> a >> x >> b >> x >> c; a += 10; printf("%04d-%02d-%02d", a, b, c); }
B-简单图形问题
思路
正方形面积:\(x^2\),正三角形面积:\(\frac{\sqrt{3}}{4} x^2\),判断一下能组成什么就行。
代码
#include <iostream> #include <cmath> using namespace std; typedef long long ll; int main() { int t; cin >> t; while (t --) { ll s; cin >> s; ll x = sqrt(s); ll y = sqrt(4 * s / sqrt(3)); if (x * x == s && y * y * sqrt(3) / 4 == s) { cout << 2 << '\n'; } else if (x * x == s) { cout << 0 << '\n'; } else if (y * y * sqrt(3) / 4 == s) { cout << 1 << '\n'; } else cout << 3 << '\n'; } return 0; }
C-小红的差值构造
思路
根据给出的目标点(x, y),如果x>0,显然U操作数量一定要比x值大,否则就不可能到达,同理其他情况也一样。
接下来讨论可行的方案数,同样以x>0的情况讨论,假设用u记录一共有多少个U操作,且U操作一定要选满x个,那么我们就从选则x个开始增加选择的数量,同时也从0开始增加反方向D操作的数量,这样保证最终结果一定到达x。根据组合数概念,就有\(C_{u}^{x+i} * C_{d}^{i}\)搭配的方案数。其他情况同理。
代码
#include <iostream> using namespace std; typedef long long ll; const int mod = 1e9 + 7; const int M = 1e6; int n, x, y; string s; ll fact[M + 10], infact[M + 10]; ll qmi(int a, int b) { ll res = 1; while(b) { if(b & 1) res = res * a % mod; a = (ll)a * a % mod; b >>= 1; } return res; } void init() { fact[0] = infact[0] = 1; for(int i = 1; i <= M; i ++) fact[i] = fact[i - 1] * i % mod; infact[M] = qmi(fact[M], mod - 2); for(int i = M - 1; i >= 1; i --) infact[i] = infact[i + 1] * (i + 1) % mod; } ll C(int a, int b) { if(b < 0 || a - b < 0) return 0; return fact[a] * infact[b] % mod * infact[a - b] % mod; } void solve() { cin >> n >> x >> y; cin >> s; int l = 0, r = 0, d = 0, u = 0; for (auto i : s) { if (i == 'L') l ++; if (i == 'R') r ++; if (i == 'D') d ++; if (i == 'U') u ++; } int L = 0, R = 0, D = 0, U = 0; if (x > 0) { if (u < x) { cout << "NO" << '\n'; return ; } U = x; } else if (x < 0) { if (d < abs(x)) { cout << "NO" << '\n'; return ; } D = abs(x); } if (y > 0) { if (r < y) { cout << "NO" << '\n'; return ; } R = y; } else if (y < 0) { if (l < abs(y)) { cout << "NO" << '\n'; return ; } L = abs(y); } cout << "YES" << ' '; ll s1 = 0; if (x >= 0) { for (int i = 0; i <= min(u - U, d); i ++) s1 = (s1 + C(u, U + i) * C(d, i) % mod) % mod; } else { for (int i = 0; i <= min(d - D, u); i ++) s1 = (s1 + C(d, D + i) * C(u, i) % mod) % mod; } ll s2 = 0; if (y < 0) { for (int i = 0; i <= min(l - L, r); i ++) s2 = (s2 + C(l, L + i) * C(r, i) % mod) % mod; } else { for (int i = 0; i <= min(r - R, l); i ++) s2 = (s2 + C(r, R + i) * C(l, i) % mod) % mod; } for (int i = 0; i < n; i ++) { if (U && s[i] == 'U') { cout << s[i]; U --; } if (D && s[i] == 'D') { cout << s[i]; D --; } if (L && s[i] == 'L') { cout << s[i]; L --; } if (R && s[i] == 'R') { cout << s[i]; R --; } } cout << ' ' << s1 * s2 % mod << '\n'; } int main() { init(); int t; cin >> t; while (t --) solve(); return 0; }
D-小红的差值构造
思路
根据题意,就是到x和y两个点的最短距离之和的最小值。分情况讨论一下,要么x和y都在1~n以内,要么一个在外面,一个在里面。很显然的,要贪最小,就是位置最中间的时候(证明不会),第一个情况,x为\(mid-\frac{l}{2}\)、y为\(mid+\frac{l}{2}\),第二个情况,x为mid、y为mid+l,取这两个值的最小值。
代码
#include <iostream> using namespace std; typedef long long ll; int n, l; ll s(ll x) { return x * (x + 1) / 2; } ll func(ll x) { if (x % 2) return s(x / 2 + 1) + s(x / 2); else return s(x / 2) * 2; } void solve() { cin >> n >> l; int mid = (n + 1) / 2; int x = mid - l / 2, y = x + l; ll res = s(x - 1) + s(n - y) + func(y - x - 1); ll ans = func(n - 1); if (ans < res) cout << mid << ' ' << mid + l << ' ' << ans << '\n'; else cout << x << ' ' << y << ' ' << res << '\n'; } int main() { int t; cin >> t; while (t --) solve(); return 0; }
本文作者:Natural-TLP
本文链接:https://www.cnblogs.com/Natural-TLP/p/18426157
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步