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;
}

这么简单的题打成这个狗屎样子,我真完蛋了

好像去打提高组的题啊,但又感觉自己好菜,郁郁了

posted @ 2025-07-19 15:54  zhangch_qwq  阅读(49)  评论(0)    收藏  举报