前言
四题场,wida哥致敬传奇周赛1,如果有问题欢迎大家评论或私信指出
题解
A.Letter Song ~ 致十年后的我们
把年份加10即可,大家可以按照自己的方式,我是用字符串读入,把年份转成了整型再去给这个数字加10。
#include<bits/stdc++.h>
using i64 = long long;
void solve() {
std::string s;
std::cin >> s;
int ans = 0;
for (int i = 0; i < 4; i++) {
ans = ans * 10 + (s[i] - '0');
}
std::cout << ans + 10;
for (int i = 4; i < s.size(); i++) {
std::cout << s[i];
}
}
signed main() {
std::ios::sync_with_stdio(0);
std::cout.tie(0);
std::cin.tie(0);
i64 t = 1;
// std::cin >> t;
while (t--) {
solve();
}
}
B.简单图形问题 - 0123
根据三角形和正方形的面积计算公式,我们发现如果边长为整数,那这个三角形的面积不可能是整数,所以只需要判断是否是正方形就好了
#include<bits/stdc++.h>
using i64 = long long;
void solve() {
int n;
std::cin >> n;
int a = sqrt(n);
if (a * a == n) {
std::cout << 0 << '\n';
}
else {
std::cout << 3 << '\n';
}
}
signed main() {
std::ios::sync_with_stdio(0);
std::cout.tie(0);
std::cin.tie(0);
i64 t = 1;
std::cin >> t;
while (t--) {
solve();
}
}
C.小红的机器人构造 - Ⅰ+Ⅱ+Ⅲ
又是经典写屎的一天,给大家说说我的思路,然后代码仅供参考,建议自己写一下,由于题目说的是最终目的地在)所以,我输出的方案就是把多余的步骤都删掉,让他直接走到目的地,没有回头路,就比如要走到,那我就只保留对答案有贡献那三个字符,然后方案数的话,输出的方案是最短的字符串,我们先考虑把原字符串变为改串有多少种方式,就比如原字符串种有个,最简方案中只有个,那么的贡献就是,即在原来的中任选两个保留下来,然后我们去考虑左右移动不会影响上下移动,说明是独立分开的,那我们就分开考虑,从最短的开始加,比如最简方案中有个和个,我们可以再加一对不会产生影响,那把左右的方案数再加上一个组合数,就好了,上下同理,每次都拿一对一对的去加,这样才不会影响最终位置,这个说的有点乱,大家靠代码再理解一下,我简单写了点注释或者直接问我,b站牛客竞赛也会有讲题人的视频讲解。
#include<bits/stdc++.h>
using i64 = long long;
template<class T>
constexpr T power(T a, i64 b) {
T res = 1;
for (; b; b /= 2, a *= a) {
if (b % 2) {
res *= a;
}
}
return res;
}
constexpr i64 mul(i64 a, i64 b, i64 p) {
i64 res = a * b - i64(1.L * a * b / p) * p;
res %= p;
if (res < 0) {
res += p;
}
return res;
}
template<int P>
struct MInt {
int x;
constexpr MInt() : x{} {}
constexpr MInt(i64 x) : x{norm(x % getMod())} {}
static int Mod;
constexpr static int getMod() {
if (P > 0) {
return P;
} else {
return Mod;
}
}
constexpr static void setMod(int Mod_) {
Mod = Mod_;
}
constexpr int norm(int x) const {
if (x < 0) {
x += getMod();
}
if (x >= getMod()) {
x -= getMod();
}
return x;
}
constexpr int val() const {
return x;
}
explicit constexpr operator int() const {
return x;
}
constexpr MInt operator-() const {
MInt res;
res.x = norm(getMod() - x);
return res;
}
constexpr MInt inv() const {
assert(x != 0);
return power(*this, getMod() - 2);
}
constexpr MInt &operator*=(MInt rhs) & {
x = 1LL * x * rhs.x % getMod();
return *this;
}
constexpr MInt &operator+=(MInt rhs) & {
x = norm(x + rhs.x);
return *this;
}
constexpr MInt &operator-=(MInt rhs) & {
x = norm(x - rhs.x);
return *this;
}
constexpr MInt &operator/=(MInt rhs) & {
return *this *= rhs.inv();
}
friend constexpr MInt operator*(MInt lhs, MInt rhs) {
MInt res = lhs;
res *= rhs;
return res;
}
friend constexpr MInt operator+(MInt lhs, MInt rhs) {
MInt res = lhs;
res += rhs;
return res;
}
friend constexpr MInt operator-(MInt lhs, MInt rhs) {
MInt res = lhs;
res -= rhs;
return res;
}
friend constexpr MInt operator/(MInt lhs, MInt rhs) {
MInt res = lhs;
res /= rhs;
return res;
}
friend constexpr std::istream &operator>>(std::istream &is, MInt &a) {
i64 v;
is >> v;
a = MInt(v);
return is;
}
friend constexpr std::ostream &operator<<(std::ostream &os, const MInt &a) {
return os << a.val();
}
friend constexpr bool operator==(MInt lhs, MInt rhs) {
return lhs.val() == rhs.val();
}
friend constexpr bool operator!=(MInt lhs, MInt rhs) {
return lhs.val() != rhs.val();
}
};
template<>
int MInt<0>::Mod = 998244353;
template<int V, int P>
constexpr MInt<P> CInv = MInt<P>(V).inv();
constexpr int P = 1000000007;
using Z = MInt<P>;
struct Comb {
int n;
std::vector<Z> _fac;
std::vector<Z> _invfac;
std::vector<Z> _inv;
Comb() : n{0}, _fac{1}, _invfac{1}, _inv{0} {}
Comb(int n) : Comb() {
init(n);
}
void init(int m) {
m = std::min(m, Z::getMod() - 1);
if (m <= n) return;
_fac.resize(m + 1);
_invfac.resize(m + 1);
_inv.resize(m + 1);
for (int i = n + 1; i <= m; i++) {
_fac[i] = _fac[i - 1] * i;
}
_invfac[m] = _fac[m].inv();
for (int i = m; i > n; i--) {
_invfac[i - 1] = _invfac[i] * i;
_inv[i] = _invfac[i] * _fac[i - 1];
}
n = m;
}
Z fac(int m) {
if (m > n) init(2 * m);
return _fac[m];
}
Z invfac(int m) {
if (m > n) init(2 * m);
return _invfac[m];
}
Z inv(int m) {
if (m > n) init(2 * m);
return _inv[m];
}
Z binom(int n, int m) {
if (n < m || m < 0) return 0;
return fac(n) * invfac(m) * invfac(n - m);
}
} comb;
void solve() {
int n, x, y;
std::cin >> n >> x >> y;
std::string s;
std::cin >> s;
s = ' ' + s;
i64 cntl = 0, cntr = 0, cntu = 0, cntd = 0;
for (int i = 1; i <= n; i++) {
if (s[i] == 'L') {
cntl++;
}
else if (s[i] == 'R') {
cntr++;
}
else if (s[i] == 'U') {
cntu++;
}
else {
cntd++;
}
}
if (x > 0) {
if (cntu < x) {
std::cout << "NO" << '\n';
return;
}
if (y > 0) {
if (cntr < y) {
std::cout << "NO" << '\n';
return;
}
}
else {
if (cntl < -y) {
std::cout << "NO" << '\n';
return;
}
}
}
else {
if (cntd < -x) {
std::cout << "NO" << '\n';
return;
}
if (y > 0) {
if (cntr < y) {
std::cout << "NO" << '\n';
return;
}
}
else {
if (cntl < -y) {
std::cout << "NO" << '\n';
return;
}
}
}
std::cout << "YES" << ' ';
i64 resl = cntl, resr = cntr, resu = cntu, resd = cntd;
int x1 = x, y1 = y;
for (int i = 1; i <= n; i++) {
if (s[i] == 'U') {
if (x1 > 0) {
x1 -= 1;
cntu -= 1;
std::cout << s[i];
}
}
else if (s[i] == 'D') {
if (x1 < 0) {
x1 += 1;
cntd -= 1;
std::cout << s[i];
}
}
else if (s[i] == 'R') {
if (y1 > 0) {
y1 -= 1;
cntr -= 1;
std::cout << s[i];
}
}
else {
if (y1 < 0) {
y1 += 1;
cntl -= 1;
std::cout << s[i];
}
}
}
// std::cout << cntl << ' ' << cntr << ' ' << cntu << ' ' << cntd << '\n';
std::cout << ' ';
Z ans = 0, ans1 = 0, ans2 = 0;
// ans += comb.binom(resl, cntl) * comb.binom(resr, cntr) * comb.binom(resu, cntu) * comb.binom(resd, cntd);
ans1 += comb.binom(resl, cntl) * comb.binom(resr, cntr);//res是每个操作的总个数
ans2 += comb.binom(resu, cntu) * comb.binom(resd, cntd);//cnt是每个操作要删掉几个。
cntl = resl - cntl, cntr = resr - cntr, cntu = resu - cntu, cntd = resd - cntd;//到这里cnt变成了每个操作要保留多少个
for (int i = 1; cntl + i <= resl && cntr + i <= resr; i++) {
ans1 += comb.binom(resl, cntl + i) * comb.binom(resr, cntr + i);
}
for (int i = 1; cntu + i <= resu && cntd + i <= resd; i++) {
ans2 += comb.binom(resu, cntu + i) * comb.binom(resd, cntd + i);
}
// std::cout << ans1 << ' ' << ans2 << '\n';
ans *= ans1 + ans2;
// ans *= ans1 * ans2;
// ans += cntl * cntr + cntu * cntd + cntl * cntr * cntu * cntd;
std::cout << ans1 * ans2<< '\n';
}
signed main() {
std::ios::sync_with_stdio(0);
std::cout.tie(0);
std::cin.tie(0);
i64 t = 1;
std::cin >> t;
while (t--) {
solve();
}
}
D.小红的差值构造 - easy+hard+extreme
这个属于是数学方法硬推了,我不会证明答案的正确性,首先我们发现,如果目标区间的长度大于数组长度了,肯定是把区间的一端放在中位数上。否则的话,就是把目标区间的尽可能的去围绕着的中位数,就比如的中位数是,目标区间长度是,那我目标区间的就是。如果目标区间长度是,那我的目标区间的就是。可以算出来,剩下的就全是等差数列求和,大家手玩一下就能发现等差数列的规律,如果出现了这样的数列,分奇偶就能看成两个等差数列了,数列长度也可以直接计算,代码仅供参考。
#include<bits/stdc++.h>
using i64 = long long;
void solve() {
int n, k;
std::cin >> n >> k;
if (k >= n) {
i64 n1 = (n + 1) / 2, n2 = n / 2;
std::cout << (n + 1) / 2 << ' ' << (n + 1) / 2 + k << ' ' << (n1 - 1) * n1 / 2 + (1 + n2) * n2 / 2 << '\n';
return;
}
int pos = (n + 1) / 2;
i64 l = pos - k / 2, r = pos + (k + 1) / 2;
i64 ans = 0;
ans += l * (l - 1) / 2;
ans += (n - r) * (n - r + 1) / 2;
i64 n1 = (k + 2) / 2, n2 = (k + 1) / 2;
ans += (n1 - 1) * n1 / 2 + (n2 - 1) * n2 / 2;
// std::cout << n1 << ' ' << n2 << '\n';
std::cout << l << ' ' << r << ' ' << ans << '\n';
}
signed main() {
std::ios::sync_with_stdio(0);
std::cout.tie(0);
std::cin.tie(0);
i64 t = 1;
std::cin >> t;
while (t--) {
solve();
}
}