2025.7.19 CSP-J模拟赛【7】
T1 序列嵌套
map简单题不多说
#include<bits/stdc++.h>
using namespace std;
int n,a[100005],b[100005],c[100005];
int num[100005],sum[100005];
map<int,int> mp;
vector<int> q[100005];
long long ans;
int main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++){
cin>>b[i];
mp[b[i]]=1;
q[b[i]].push_back(i);
}
for(int i=1;i<=n;i++){
cin>>c[i];
num[c[i]]++;
}
for(int i=1;i<=n;i++){
mp[b[i]]=1;
sum[b[i]]+=num[i];
}
for(int i=1;i<=n;i++){
if(mp[a[i]]){
ans+=sum[a[i]];
}
}
cout<<ans;
return 0;
}
T2 最小的公倍数小题
容易发现第一位一定是1,又因为被2、5整除所以最后一位一定是0,枚举倒数第三、倒数第二位根据3和7的倍数性质判断
#include<bits/stdc++.h>
using namespace std;
int n,a[100005],b[100005],c[100005];
int num[100005],sum[100005];
map<int,int> mp;
vector<int> q[100005];
long long ans;
int main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++){
cin>>b[i];
mp[b[i]]=1;
q[b[i]].push_back(i);
}
for(int i=1;i<=n;i++){
cin>>c[i];
num[c[i]]++;
}
for(int i=1;i<=n;i++){
mp[b[i]]=1;
sum[b[i]]+=num[i];
}
// for(int i=1;i<=n;i++){
// for(int j=1;j<=n;j++){
// cout<<a[i]<<" "<<c[j]<<" "<<b[c[j]]<<"\n";
// if(c[j]<=n&&a[i]==b[c[j]]){
// ans++;
// }
// }
// }
// cout<<ans<<"\n";ans=0;
for(int i=1;i<=n;i++){
if(mp[a[i]]){
ans+=sum[a[i]];
}
}
cout<<ans;
return 0;
}
T3 选点
两点最远距离是首尾距离除以段数,二分判断即可
注意题目里面没有明确说明顺序就一定要排序,不要想当然是正序直接二分!!!
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll m,n,pj,l,r,ans;
struct node{
int a,b;
}e[100005];
ll a[100005],b[100005];
bool cmp(node a,node b){
return a.a<b.a;
}
ll pd(ll x){
ll xf=lower_bound(b+1,b+m+1,x)-b;
ll xs=upper_bound(a+1,a+m+1,x)-a;
if(xs==xf+1) return 0;
else return xf;
}
bool check(ll x){
ll zb=a[1];
for(ll i=2;i<n;i++){
int sul=pd(zb+x);
if(sul>m) return 0;
if(sul==0)
zb+=x;
else{
zb=a[sul];
}
}
if(b[m]-zb<x) return 0;
else return 1;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin>>n>>m;
for(int i=1;i<=m;i++) cin>>a[i]>>b[i];
sort(a+1,a+m+1);
sort(b+1,b+m+1);
pj=(b[m]-a[1]+1)/(n-1);
l=0,r=pj;
while(l<=r){
ll mid=(l+r)>>1;
if(check(mid)) ans=mid,l=mid+1;
else r=mid-1;
}
cout<<ans;
return 0;
}
T4 划分数组
容易写出爆搜或者 \(n^3\) 的DP,考虑优化
注意到转移的前提是两者关于此段同余,用t存下关于这段同余的dp和,可以 \(O(1)\) 更新,时间复杂度就来到了 \(O(n^2)\)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int MAXN=3005;
const ll mod=1e9+7;
ll n,s[MAXN],ans;
ll f[MAXN],t[MAXN][MAXN];
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin>>n;
t[1][0]=1;
for(ll i=1;i<=n;++i){
cin>>s[i];s[i]+=s[i-1];
for(int j=1;j<=i;j++) f[j]=t[j][s[i]%j];
for(int j=1;j<=i;j++) t[j+1][s[i]%(j+1)]=(t[j+1][s[i]%(j+1)]+f[j])%mod;
}
for(int i=1;i<=n;i++)
ans=(ans+f[i])%mod;
cout<<ans;
return 0;
}
这么简单的题打成这个狗屎样子,我真完蛋了
好像去打提高组的题啊,但又感觉自己好菜,郁郁了
本文来自博客园,作者:zhangch_qwq,转载请注明原文链接:https://www.cnblogs.com/zhangchenhua-awa/p/18992964

浙公网安备 33010602011771号