2025CSP-J复赛试题解析
复赛没考好,写题解以泄愤
致敬传奇#Shang6Shan3Ruo3Shui3🫡
T1 拼数
题目传送门
**题意:**提取所有的数字并进行降序排列
方法比较多,例如全存到数组中进行排序,桶计数进行输出,或vector自动排序等。
数组排序方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #include<bits/stdc++.h> using namespace std; const int N=1e6+5; string s; int a[N]; int main(){ ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin>>s; int len=s.size(); int cnt=0; for(int i=0;i<len;i++){ if(s[i]>='0'&&s[i]<='9'){ a[++cnt]=s[i]-'0'; } } sort(a+1,a+cnt+1); for(int i=cnt;i>=1;i--) cout<<a[i]; return 0; }
|
T2 座位
题目传送门
**题意:**蛇形排座
既然是有规律的排座问题,显然可以用数学解决。不难发现需要讨论是单数列还是双数列,这样就可以知道是从前往后还是从后往前了。要注意输入先行后列,输出先列后行。
方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| #include<bits/stdc++.h> using namespace std; const int N=105; int n,m; int a[N]; int main(){ ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin>>n>>m; int r; cin>>r; int cnt=0; for(int i=2;i<=n*m;i++){ int num; cin>>num; if(num>r) cnt++; } cnt++; int a=cnt/n,b=cnt%n; if(b==0){ cout<<a<<" "; if(a%2==0){ cout<<1; }else{ cout<<n; } }else{ cout<<a+1<<" "; if((a+1)%2==0){ cout<<n-b+1; }else{ cout<<b; } } return 0; }
|
T3 异或和
题目传送门
**题意:**找出异或和为k的区间的数量数
区间相关首先考虑前缀和(如果a xor b=c有c xor a=b即异或为自身的逆运算),数量数相关考虑dp,
方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #include<bits/stdc++.h> using namespace std; const int N=5e5+5; int n,k; int a[N],b[N]; int f[N]; int l[1<<20+1]; int main(){ ios::sync_with_stdio(false),cout.tie(0),cin.tie(0); cin>>n>>k; for(int i=1;i<=n;i++){ cin>>a[i]; b[i]=a[i]^b[i-1]; } memset(l,-1,sizeof(l)); l[0]=0; for(int i=1;i<=n;i++){ f[i]=f[i-1]; if(l[b[i]^k]>=0){ f[i]=max(f[i],f[l[b[i]^k]]+1); } l[b[i]]=i; } cout<<f[n]<<endl; return 0; }
|
T4 多边形
题目传送门
**题意:**找出可以拼成多边形的木棍方案个数(即满足∑i=1m⋅li>2×maxi=1m⋅li )。
不想写了 dp即可
