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;
}