RetOI Round 2 选手题解
2026-02-21 19:06:53
发布于:广东
打完了。不算别的东西大概是115minAK的。
T1
题目大意:给你一坨字符,计算每个字符的ASCII码的积
其实刚一开看见这道题是有点慌的,以为要把所有特殊字符写出来。
但其实把一个字符强转成 就是其 ASCII 值了,简单。
然后注意到本题需要高精度,需要写一个高精乘低精。
时间复杂度:。
体感难度:橙。
#include<bits/stdc++.h>
using namespace std;
#define int long long
int c[2000009];
signed main(){
c[1] = 1;
char x;
int n = 1;
while(cin>>x){
int b = x,sum = 0;
//cout<<b;
for(int i = 1;i<=n;++i){
int newc = c[i]*b+sum;
sum = newc/10,c[i] = newc%10;
}
while(sum){
c[++n] = sum%10;
sum/=10;
}
}
for(int i = n;i>=1;--i){
cout<<c[i];
}
}
T2
题目大意:求第 年至第 年之间的闰年个数。
直接求 之间的闰年个数是复杂且麻烦的,需要处理很多边界情况。
不妨利用前缀和的思想,计算区间 和 ,相减即为 。
然后考虑怎么求 。闰年的规律是“四年一润,百年不润,四百年再润”。所以答案为 。
时间复杂度:。
体感难度:红
l--;
cout<<r/4-r/100+r/400-(l/4-l/100+l/400);
T3
题目大意:不可描述
简单的区间 。定义 表示目前这个人能不能赢。
初始状态 ,就剩一个字符肯定能赢。
然后对于题目中四种操作分别转移即可:
-
- DP 跑两边,跨度为 。
-
- 直接DP收缩。
-
- DP 跑两边,跨度为 。
-
- DP跑幸运字符那边,跨度为 。
时间复杂度:
体感难度:黄。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const string pp = "Piplong";
bool f[109][109];
bool check(char x){
for(auto i:pp){
if(x == i) return 1;
}
return 0;
}
void solve(){
for(int i = 1;i<=105;++i){
for(int j = 1;j<=105;++j){
f[i][j] = 0;
}
}
string s;
cin>>s;
int n = s.size();
s = " "+s;
for(int i = 1;i<=n;++i){
f[i][i] = 1;
}
for(int len = 2;len<=n;++len){
for(int l = 1;l+len-1<=n;++l){
int r = l+len-1;
char lc = s[l],rc = s[r];
bool lb = check(lc),rb = check(rc);
if(lc == rc){
if(r-l == 1) f[l][r] = 1;
else f[l][r] = !(f[l+1][r-1]);
continue;
}
if(lb&&rb){
if(l+2>r||!f[l+2][r]||l>r-2||!f[l][r-2]) f[l][r] = 1;
}else if(!lb&&!rb){
if(l+1>r||!f[l+1][r]||l>r-1||!f[l][r-1]) f[l][r] = 1;
}else{
if(lb) f[l][r] = !f[l+1][r];
else f[l][r] = !f[l][r-1];
}
}
}
if(f[1][n]) cout<<"lz will win.\n";
else cout<<"pzh will win.\n";
}
signed main(){
int t;
cin>>t;
while(t--){
solve();
}
}
T4
求哈密顿路径是否存在
这个问题请读者自行学习一部分。
哈密顿路径,就是说在一个有限的网格图里面,从一个格子开始,能否不重不漏的走完所有格子。也就是本题问的。
首先如果总的格子数为奇数,对于所有格子 ,此时 是偶数的格子比 是奇数的格子要多一个,此时你要看的是 的奇偶性, 必须是偶数,你才能走出来这样的路径。
否则总格子数是偶数,对于随便一组 , 的上下左右至少有一个方向距离为偶数个格子,一定能走出一条“蛇形”的哈密顿路径。
注意 的狭长网格图是个特例,你必须在这个网格左右其中一端才行。
时间复杂度:。
体感难度:黄。
#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve(){
int n,m,x,y;
cin>>n>>m>>x>>y;
if(n == 1){
cout<<(y == 1||y == m?"Yes":"No");
return ;
}
if(m == 1){
cout<<(x == 1||x == n?"Yes":"No");
return ;
}
if(n&1&&m&1){
if((x+y)&1) cout<<"No";
else cout<<"Yes";
return ;
}
cout<<"Yes";
}
signed main(){
int t;
cin>>t;
while(t--){
solve();
cout<<'\n';
}
}
T5-ex
难度还是有的,感觉没有大家说的那么不堪)也可能是我太蠢了。
虽然题目中没有明确给出,但是 不超时的显然可以朴素 解决。
下文中 表示组合数, 个里面选 个。
对于正解:考虑计算所有经过了 的路径。方案数显然为 。这个读者应该能理解。
然后,我们令 ,所有 的 的总贡献为:
读者自证不难读者自证不难读者自证不难对不起懒得写具体化简过程。当你把式子化简,你就会发现这个式子的值与 无关!变成了 。也就是说对于每个质数带来的贡献都是 。
分析到这里就豁然开朗,答案为 的质数个数 ,于是预处理质数筛算质数,预处理阶乘和逆元计算出组合数,本题就可以阿里嘎多妈妈哈哈的AC掉了。记得取模哦。
时间复杂度:
体感难度:绿上蓝下。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2000010;
bool vis[N];
void sieve(int n){
vis[0] = vis[1] = true;
for(int i = 2;i<=n/i;i++){
if(!vis[i]){
for(int j = i*i;j<=n;j+=i){
vis[j] = true;
}
}
}
}
int lp = 0;
void Pick(int n){
for(int i = 2;i<=n;i++){
if(!vis[i]) lp++;
}
}
int ksm(int a,int b){
int ans = 1;
while(b){
if(b&1) ans = ans*a%mod;
a = a*a%mod;
b>>=1;
}
return ans;
}
int jc[N],ny[N];
void make(int n){
jc[0] = 1;
for(int i = 1;i<=n;++i){
jc[i] = jc[i-1]*i%mod;
}
ny[n] = ksm(jc[n],mod-2);
for(int i = n-1;i>=0;--i){
ny[i] = ny[i+1]*(i+1)%mod;
}
}
int zuheshu(int n,int m){
return jc[n]*ny[m]%mod*ny[n-m]%mod;
}
int n,m;
signed main(){
cin>>n>>m;
sieve(n+m);
Pick(n+m);
make(n+m);
int c = zuheshu(n+m-2,n-1);
cout<<lp*(c%mod)%mod;
}
另外,不要抄我的代码哦,留了点小惊喜,抄了肯定过不了。但是不影响观看
全部评论 2
@AC君 求置顶
2小时前 来自 广东
0
素质这一块/.
2小时前 来自 广东
0ppl 最文明的一集(doge
1小时前 来自 浙江
0
















有帮助,赞一个