A 树之荣荣 青梅熙熙
树之荣荣 青梅熙熙
这个题是一个经典的博弈问题。我们可以考虑一种情况,就是你每一次都会取一个。那么最后一个你肯定不能取。所以我们可以考虑减去一个后的值。判断它的和是奇数还是偶数即可。
int n; cin >> n;
int s = 0;
for (int i = 1; i <= n; i ++)
{
int x; cin >> x;
s += x - 1;
}
if (s & 1)
{
cout << "shuai";
}
else cout << "tian";
B 夏蝉鸣鸣 两心惶惶
夏蝉鸣鸣 两心惶惶
这个题目当时打的时候没有认真看题。错了好多次。轻敌了。下次一定要认真看题目。
这个题的话主要是考了一个字符储存的问题。注意要倒着对这个字符进行更新。记录一下最后一个字符,最后把第一个字符赋给它即可。
下面是代码。
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
constexpr int N = 1e3 + 10;
int g[N][N];
struct node
{
int op, c;
} a[N];
void solve()
{
int n, m, x, y;
cin >> n >> m >> x >> y;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
char ch;
cin >> ch;
g[i][j] = ch - 'a';
}
}
int p, q;
cin >> p >> q;
for (int k = 1; k <= q; k++)
{
int op, c;
cin >> op >> c;
a[k].op = op, a[k].c = c;
}
while (p --)
for (int k = 1; k <= q; k++)
{
int op = a[k].op, c = a[k].c;
if (op == 1)
{
int u = g[c][m];
for (int i = m; i >= 1; i--)
{
g[c][i] = g[c][i - 1];
}
g[c][1] = u;
}
else
{
int u = g[n][c];
for (int i = n; i >= 1; i--)
{
g[i][c] = g[i - 1][c];
}
g[1][c] = u;
}
}
cout << char('a' + g[x][y]);
return;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
// cin >> t;
while (t--)
{
solve();
}
return 0;
}
C 田垄恹恹 我心难言
田垄恹恹 我心难言
这个题目我们对 n == 1 和 n == 2 的情况进行特判一下。如果 n == 1 的话很容易知道肯定不可以成立的。对于n == 2 的情况。
1 2 2 1
1 2 这种情况也是不可以的。1 2 这种情况就是去掉 1 或者 2 都行。所以答案是 1
那么对于 n == 3 的时候我们可以玩一下样例就知道
1 2 3
1 2 3 这种情况,就是 1。我们取 2 2 就行了。
1 3 2
1 2 3 这种情况 2 2,也是 1。所以我们判断这两种情况是 1,其他的话,我们可以证明 2 次一定可以完成。你总是可以找到一组满足条件。可以自己玩一下数字看看。
代码
int n;
cin >> n;
vector<int> a(n + 1);
vector<int> b(n + 1);
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++)
cin >> b[i];
if (n == 1)
{
cout << -1 << "\n";
return ;
}
else if (n == 2)
{
bool flag = true;
for (int i = 1; i <= n; i ++)
if (a[i] != b[i]) flag = false;
if (flag)
{
cout << -1 << "\n";
return ;
}
}
int ans;
bool flag = false;
for (int i = 1; i <= n; i++)
{
if ((a[i] == b[i] && i != n && i != 1) || a[i] == b[i + 1] || a[i] == b[i - 1])
flag = true;
}
if (flag)
ans = 1;
else
ans = 2;
cout << ans << "\n";
D 淇水汤汤 渐车帷裳
淇水汤汤 渐车帷裳
这个题就跟着题目模拟就行了。感觉没有什么好说的。看代码吧。
int n, m;
cin >> m >> n;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
cin >> g[i][j];
}
char s;
int x, y, k;
cin >> x >> y >> s >> k;
char tow = s;
while (k--)
{
// cout << x << " " << y << "\n";
if (tow == 'U')
{
y -= 1;
}
else if (tow == 'D')
{
y += 1;
}
else if (tow == 'L')
{
x -= 1;
}
else
{
x += 1;
}
if (tow == 'U')
{
if (g[x][y])
{
tow = 'R';
g[x][y] = 0;
}
else
{
tow = 'L';
g[x][y] = 1;
}
}
else if (tow == 'D')
{
if (g[x][y])
{
tow = 'L';
g[x][y] = 0;
}
else
{
tow = 'R';
g[x][y] = 1;
}
}
else if (tow == 'L')
{
if (g[x][y])
{
tow = 'U';
g[x][y] = 0;
}
else
{
tow = 'D';
g[x][y] = 1;
}
}
else
{
if (g[x][y])
{
tow = 'D';
g[x][y] = 0;
}
else
{
tow = 'U';
g[x][y] = 1;
}
}
}
cout << x << " " << y;
F 执子之手 与子偕老
执子之手 与子偕老
我们找一下十万以内和甜美互质的数即可。gcd 是一个求最大公约数的函数。
int n; cin >> n;
int ans = 0;
for (int i = 2; i <= 100000; i ++)
{
if (__gcd(i, n) == 1) ans ++;
}
cout << ans;
G 舒窈纠兮 劳心悄兮
舒窈纠兮 劳心悄兮
这个题目用 dp 可以做出来。
我们可以把 ILLLYY 看成是 6 个元素,那么每一个元素都要之前所有的元素都存在才有意义。我们可以用 dp 来储存一下之前已经得到的值。 比如说 dp[i][j] 就是原来数组从一开始到第 i 个元素,最后结尾为 mo[j] 的最大数量。通过维护这样一个数组可以得到最后最终的答案。
要每一次更新一下 dp[i][j] = dp[i - 1][j]; 这个是要复制一下上一次的值。
如果发现现在的字符和遍历到的模板串上一个字符相同,那么我们可以更新一下。
dp[i][j] = dp[i][j] + dp[i-1][j-1]; // 加上 i - 1 的以 mo[j-1]为结尾的值。
要注意i最一开始的时候对 dp 进行一个初始化。令 dp[i][0] = 1; 即可。
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
constexpr int M = 1314520;
constexpr int N = 1e6 + 10;
int dp[N][7];
void solve()
{
string s = "";
for (int i = 1; i <= 1314; i++)
s += "ILOVEYOU";
int len = s.size();
string mo = "ILLLYY";
for (int i = 0; i <= len; i++)
{
dp[i][0] = 1;
}
for (int i = 1; i <= len; i++)
{
for (int j = 1; j <= 6; j++)
{
dp[i][j] = dp[i - 1][j];
if (s[i - 1] == mo[j - 1])
{
dp[i][j] = (dp[i][j] + dp[i - 1][j - 1]) % M;
}
}
}
cout << dp[len][6];
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
// cin >> t;
while (t--)
{
solve();
}
return 0;
}
H 子兴视夜 明星有烂
子兴视夜 明星有烂
这个直接让 m / n 即可。因为 c/c++ 是向下取整,所以直接除以即可。
int n, m; cin >> n >> m;
cout << m / n;
I 无思远人 劳心怛怛
无思远人 劳心怛怛
背一下诗就好了。哈哈,考试的时候没看题就瞎做,还错了一次。逆天。
string s1 = "床前明月光";
string s2 = "疑是地上霜";
string s3 = "举头望明月";
string s4 = "低头思故乡";
string s; cin >> s;
if (s == s1) cout << s2;
if (s == s2) cout << s1;
if (s == s3) cout << s4;
if (s == s4) cout << s3;
J 鹤鸣九皋 声闻于野
鹤鸣九皋 声闻于野
这个题用莫队写。然后对异或处理一下前缀和即可。
import sys
from collections import defaultdict
def main():
input = sys.stdin.read
data = input().split()
ptr = 0
n = int(data[ptr])
ptr += 1
q = int(data[ptr])
ptr += 1
k = int(data[ptr])
ptr += 1
a = list(map(int, data[ptr:ptr + n]))
ptr += n
# 构建前缀异或数组
pre = [0] * (n + 1)
for i in range(1, n + 1):
pre[i] = pre[i - 1] ^ a[i - 1]
queries = []
for _ in range(q):
l = int(data[ptr])
ptr += 1
r = int(data[ptr])
ptr += 1
s = l - 1
e = r
queries.append((s, e, _))
block_size = int(n ** 0.5) + 1
queries.sort(key=lambda x: (x[0] // block_size, x[1]))
current_l = 0
current_r = 0
current_ans = 0
count = defaultdict(int)
count[pre[0]] = 1
res = [0] * q
for s, e, idx in queries:
# 调整左边界
while current_l > s:
current_l -= 1
x = pre[current_l]
current_ans += count.get(x ^ k, 0)
count[x] += 1
while current_l < s:
x = pre[current_l]
count[x] -= 1
current_ans -= count.get(x ^ k, 0)
if count[x] == 0:
del count[x]
current_l += 1
# 调整右边界
while current_r < e:
current_r += 1
x = pre[current_r]
current_ans += count.get(x ^ k, 0)
count[x] += 1
while current_r > e:
x = pre[current_r]
count[x] -= 1
current_ans -= count.get(x ^ k, 0)
if count[x] == 0:
del count[x]
current_r -= 1
res[idx] = current_ans
for ans in res:
print(ans)
if __name__ == "__main__":
main()

555

被折叠的 条评论
为什么被折叠?



