【超好懂的比赛题解】2022 年远光杯程序设计竞赛

本文记录了2022年远光杯程序设计竞赛的多个题目,包括题目的解题思路和部分代码实现,涉及ACM、欧拉函数、矩阵快速幂、平衡二叉搜索树、字符串处理等多个算法和数据结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


title : 2022 年远光杯程序设计竞赛
date : 2022-6-2
tags : ACM,题解,练习记录
author : Linno


2022 年远光杯程序设计竞赛

题目链接:https://oj.kexie.club/problems

补题进度:9/12

「2022 远光杯」三生万物

打了个10*10的表,然后发现只需要确定m=1和m=n-1的情况即可。

//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define int long long
using namespace std;
const int N=2e5+7;
const int mod=1e9+7;

//int read(){	int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
//void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}
map<int,string>mp[20];
int n,m;

void Solve(){mp[1][0]="MUST";
mp[1][1]="IMPOSSIBLE";
mp[2][0]="MUST";
mp[2][1]="IMPOSSIBLE";
mp[2][2]="MUST";
mp[3][0]="MUST";
mp[3][1]="IMPOSSIBLE";
mp[3][2]="MAYBE";
mp[3][3]="IMPOSSIBLE";
mp[4][0]="MUST";
mp[4][1]="IMPOSSIBLE";
mp[4][2]="MAYBE";
mp[4][3]="IMPOSSIBLE";
mp[4][4]="MUST";
mp[5][0]="MUST";
mp[5][1]="IMPOSSIBLE";
mp[5][2]="MAYBE";
mp[5][3]="MAYBE";
mp[5][4]="MAYBE";
mp[5][5]="IMPOSSIBLE";
mp[6][0]="MUST";
mp[6][1]="IMPOSSIBLE";
mp[6][2]="MAYBE";
mp[6][3]="MAYBE";
mp[6][4]="MAYBE";
mp[6][5]="IMPOSSIBLE";
mp[6][6]="MUST";
mp[7][0]="MUST";
mp[7][1]="IMPOSSIBLE";
mp[7][2]="MAYBE";
mp[7][3]="MAYBE";
mp[7][4]="MAYBE";
mp[7][5]="MAYBE";
mp[7][6]="MAYBE";
mp[7][7]="IMPOSSIBLE";
mp[8][0]="MUST";
mp[8][1]="IMPOSSIBLE";
mp[8][2]="MAYBE";
mp[8][3]="MAYBE";
mp[8][4]="MAYBE";
mp[8][5]="MAYBE";
mp[8][6]="MAYBE";
mp[8][7]="IMPOSSIBLE";
mp[8][8]="MUST";
mp[9][0]="MUST";
mp[9][1]="IMPOSSIBLE";
mp[9][2]="MAYBE";
mp[9][3]="MAYBE";
mp[9][4]="MAYBE";
mp[9][5]="MAYBE";
mp[9][6]="MAYBE";
mp[9][7]="MAYBE";
mp[9][8]="MAYBE";
mp[9][9]="IMPOSSIBLE";
mp[10][0]="MUST";
mp[10][1]="IMPOSSIBLE";
mp[10][2]="MAYBE";
mp[10][3]="MAYBE";
mp[10][4]="MAYBE";
mp[10][5]="MAYBE";
mp[10][6]="MAYBE";
mp[10][7]="MAYBE";
mp[10][8]="MAYBE";
mp[10][9]="IMPOSSIBLE";
mp[10][10]="MUST";
	cin>>n>>m;
	if(n<=10){
		cout<<mp[n][m]<<"\n";
	}else{
		if(m==0) cout<<"MUST\n";
		else if(m==1) cout<<"IMPOSSIBLE\n";
		else if(m==n){
			if(n&1) cout<<"IMPOSSIBLE\n";
			else cout<<"MUST\n";
		}else if(m==n-1){
			if(n&1) cout<<"MAYBE\n";
			else cout<<"IMPOSSIBLE\n";
		}else cout<<"MAYBE\n";
	}
}

signed main(){
//	ios::sync_with_stdio(0);
//	cin.tie(0);cout.tie(0);
//  freopen("in.cpp","r",stdin);
//  freopen("out.cpp","w",stdout);
	int T=1;
	cin>>T;
//	clock_t start,finish;
//	start=clock();
	while(T--){
		Solve();
	}
//	finish=clock();
//	cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl;	return 0;
}


「2022 远光杯」不只是阶乘

没写

「2022 远光杯」最长重复子序列

没写

「2022 远光杯」两点确定一条直线

又可以打表。然后差分一下发现是欧拉函数。结果就是4×sum[n-1],其中sum为欧拉函数前缀和。

//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
//#define inf 0x3f3f3f3f
#define int long long
using namespace std;
const int N=5e6+7;
const int mod=1e9+7;

//int read(){	int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
//void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}
int n,phi[N],np[N],pri[N],sum[N],cnt=0;
void Get_phi(){
	phi[1]=1;
	for(int i=2;i<N;i++){
		if(!np[i]){
			pri[++cnt]=i;
			phi[i]=i-1;
		}
		for(int j=1;j<=cnt&&i*pri[j]<N;j++){
			np[i*pri[j]]=1;
			if(i%pri[j]==0){
				phi[i*pri[j]]=pri[j]*phi[i]; //可以手动证一下
				break;
			}else phi[i*pri[j]]=(pri[j]-1)*phi[i]; //互质,积性
		}
	}
	sum[0]=0;
	for(int i=1;i<N;++i) sum[i]=sum[i-1]+phi[i];
}	
void Solve(){
	Get_phi();
	cin>>n;
	cout<<4ll*sum[n-1]<<"\n"; 
}

signed main(){
//	ios::sync_with_stdio(0);
//	cin.tie(0);cout.tie(0);
//  freopen("in.cpp","r",stdin);
//  freopen("out.cpp","w",stdout);
	int T=1;
//	cin>>T;
//	clock_t start,finish;
//	start=clock();
	while(T--){
		Solve();
	}
//	finish=clock();
//	cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl;	return 0;
}

「2022 远光杯」白羊的完美算术教室

签到。ceil()向上取整。

//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define int long long
using namespace std;
const int N=2e5+7;
const int mod=1e9+7;

//int read(){	int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
//void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}
void Solve(){
	double s;
	cin>>s;
	cout<<ceil(s/60.0)<<"\n";
}

signed main(){
//	ios::sync_with_stdio(0);
//	cin.tie(0);cout.tie(0);
//    freopen("in.cpp","r",stdin);
//  freopen("out.cpp","w",stdout);
	int T=1;
//	cin>>T;
//	clock_t start,finish;
//	start=clock();
	while(T--){
		Solve();
	}
//	finish=clock();
//	cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl;	return 0;
}

「2022 远光杯」随机播放

没写。

「2022 远光杯」递推数列的协奏曲

一看式子就知道是矩阵快速幂裸题。

//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define int long long
using namespace std;
const int N=2e5+7;
const int mod=1e9+7;

//int read(){	int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
//void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}

struct Mat{
	int a[2][2];
	Mat(){memset(a,0,sizeof(a));}
	Mat(int x){
		a[0][0]=a[1][1]=1;
		a[0][1]=a[1][0]=0;
	}
	Mat operator *(const Mat b){
		Mat res;
		for(int i=0;i<2;++i){
			for(int j=0;j<2;++j){
				for(int k=0;k<2;++k){
					res.a[i][j]+=a[i][k]*b.a[k][j]%mod;
					res.a[i][j]%=mod; 
				}
			}
		}
		return res;
	}
};

inline Mat fpow(Mat a,int b){
	Mat res(1);
	while(b){
		if(b&1) res=res*a;
		a=a*a;
		b>>=1;
	}
	return res;
}

void Solve(){
	int n,a,b,A0,B0;
	cin>>n>>a>>b;
	cin>>A0>>B0;
	Mat bas,ans;
	bas.a[0][0]=a-1;
	bas.a[0][1]=a;
	bas.a[1][0]=b;
	bas.a[1][1]=b-1;
	ans.a[0][0]=A0;
	ans.a[1][0]=B0;
	ans=fpow(bas,n)*ans;
	cout<<ans.a[0][0]%mod<<"\n";
}

signed main(){
//	ios::sync_with_stdio(0);
//	cin.tie(0);cout.tie(0);
//  freopen("in.cpp","r",stdin);
//  freopen("out.cpp","w",stdout);
	int T=1;
	cin>>T;
//	clock_t start,finish;
//	start=clock();
	while(T--){
		Solve();
	}
//	finish=clock();
//	cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl;	return 0;
}

「2022 远光杯」平衡二叉搜索树

注意审题。首先得判一下子树是否符合BST,然后再判高度差。

//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
//#define inf 0x3f3f3f3f
//#define int long long
using namespace std;
const int N=5e5+7;
const int mod=1e9+7;

//int read(){	int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
//void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}
struct node{
	int ch[2],fa,sz,val,mi,mx,hg,tg; //hg:高度,tg:是否满足BST性质 ,fg:是否满足avl性质 
}tr[N];
#define ls(x) tr[x].ch[0]
#define rs(x) tr[x].ch[1]
#define val(x) tr[x].val
#define fa(x) tr[x].fa
#define sz(x) tr[x].sz
#define hg(x) tr[x].hg
#define tg(x) tr[x].tg
#define mx(x) tr[x].mx
#define mi(x) tr[x].mi
int n,ans=1;

inline void dfs1(int x){
	mx(x)=mi(x)=val(x);
	if(ls(x)){dfs1(ls(x));mx(x)=max(mx(x),mx(ls(x)));mi(x)=min(mi(x),mi(ls(x)));}
	if(rs(x)){dfs1(rs(x));mx(x)=max(mx(x),mx(rs(x)));mi(x)=min(mi(x),mi(rs(x)));}
	sz(x)=sz(ls(x))+sz(rs(x))+1; 
	hg(x)=max(hg(ls(x)),hg(rs(x)))+1; //非叶子结点 
	tg(x)=tg(ls(x))|tg(rs(x));
	tg(x)|=(abs(hg(ls(x))-hg(rs(x)))>1);
	if(ls(x)&&mx(ls(x))>val(x)) tg(x)=1;
	if(rs(x)&&mi(rs(x))<val(x)) tg(x)=1;
	if(!tg(x)) ans=max(ans,sz(x));
	//cout<<x<<" "<<hg(x)<<" "<<tg(x)<<"\n";
}

void Solve(){
	cin>>n;
	for(int i=1;i<=n;++i){
		cin>>tr[i].val;
		tr[i].mx=tr[i].mi=val(i);
	}
	for(int i=1,u,v,w;i<n;++i){
		cin>>u>>v>>w;
		tr[u].ch[w]=v;
		tr[v].fa=u;
	}
	for(int i=1;i<=n;++i){
		if(!tr[i].fa){ //根节点 
			dfs1(i); 
			cout<<ans<<"\n";
			return;
		}
	}
}

signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
//    freopen("2.in.txt","r",stdin);
//  freopen("out.cpp","w",stdout);
	int T=1;
//	cin>>T;
//	clock_t start,finish;
//	start=clock();
	while(T--){
		Solve();
	}
//	finish=clock();
//	cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl;	return 0;
}

「2022 远光杯」再挑战转生瞬间移动

显然答案只有1、2、3三种,逐个判一下即可。

//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
//#define inf 0x3f3f3f3f
//#define int long long
using namespace std;
const int N=2e5+7;
const int mod=1e9+7;

//int read(){	int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
//void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}
int n,q,cnt[205];
string str;

inline bool check(int x,int y){
	if('a'<=str[x-1]&&str[x-1]<='z'&&'a'<=str[y-1]&&str[y-1]<='z') return 1;
	else if('A'<=str[x-1]&&str[x-1]<='Z'&&'A'<=str[y-1]&&str[y-1]<='Z') return 1;
	else if(abs(str[x-1]-str[y-1])==32) return 1;
	return 0;
}

inline bool chk2(int x,int y){
	if('a'<=str[x-1]&&str[x-1]<='z'&&cnt[str[x-1]-32]) return 1;
	if('A'<=str[x-1]&&str[x-1]<='Z'&&cnt[str[x-1]+32]) return 1;
	if('a'<=str[y-1]&&str[y-1]<='z'&&cnt[str[y-1]-32]) return 1;
	if('A'<=str[y-1]&&str[y-1]<='Z'&&cnt[str[y-1]+32]) return 1;
	return 0;
}

void Solve(){
	cin>>n>>q;
	cin>>str;
	for(int i=0;i<n;++i) ++cnt[str[i]];
	for(int i=1,x,y;i<=q;++i){
		cin>>x>>y;
		if(check(x,y)||abs(x-y)==1){
			cout<<1<<"\n";
		}else if(check(x+1,y)||check(x-1,y)||check(x,y+1)||check(x,y-1)||abs(x-y)==2){
			cout<<2<<"\n";
		}else if(chk2(x,y)){ //x或者y位置的字符存在大小写表示 
			cout<<2<<"\n";
		}else cout<<3<<"\n";
	}
}

signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
//  freopen("in.cpp","r",stdin);
//  freopen("out.cpp","w",stdout);
	int T=1;
//	cin>>T;
//	clock_t start,finish;
//	start=clock();
	while(T--){
		Solve();
	}
//	finish=clock();
//	cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl;	return 0;
}

「2022 远光杯」洗牌

链表维护一下即可。但估计我是全场唯一一个FHQ Treap了。

#include<bits/stdc++.h>
//#define int long long
#define ls(x) (T[x].ch[0])
#define rs(x) (T[x].ch[1])
#define sz(x) (T[x].sz)
#define val(x) (T[x].val)
#define pri(x) (T[x].pri)
#define fa(x) (T[x].fa)
using namespace std;
const int N=2e5+7;

int read(){	int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}

struct FHQ{
	int ch[2],val,pri,sz,fa;
}T[N];

int n,m,root=0,tot,id[N];

void update(int x){
	T[x].sz=sz(ls(x))+sz(rs(x))+1;
}

bool get(int x){
	return rs(fa(x))==x;
}

int cre(int v){ //新开辟一个结点 
    sz(++tot)=1;
    val(tot)=v;
	pri(tot)=rand();
	id[v]=tot;
    return tot;
}

int merge(int x,int y){ // 合并操作 
    if(!x||!y) return x+y; //x和y中必定有一个是0
    if(pri(x)<pri(y)){ //比较两棵树根的随机权值 
        rs(x)=merge(rs(x),y);  //把x加到左边的树上
        fa(rs(x))=x;
		update(x); //更新大小 
        return x;
    }else{
        ls(y)=merge(x,ls(y));
        fa(ls(y))=y;
        update(y);
        return y;
    }
}

void split(int x,int k,int &a,int &b,int faa=0,int fab=0){
	if(x==0){a=b=0;return;}
	if(k<=sz(ls(x)))  fa(x)=fab,b=x,split(ls(x),k,a,ls(x),faa,x);
	else fa(x)=faa,a=x,split(rs(x),k-sz(ls(x))-1,rs(x),b,x,fab);
	update(x);
}

int find(int k){
	int node=k,res=sz(ls(k))+1;
	while(node!=root&&k){
		if(get(k)) res+=sz(ls(fa(k)))+1;
		k=fa(k);
	}
	return res;
}

void Solve(){
    n=read();m=read();
   int x,y,z,w,s,t,k;
    for(int i=1;i<=n;i++){ //插入 
    	s=read();
		split(root,i-1,x,y);
		root=merge(merge(x,cre(s)),y);
	}
//	for(int i=1;i<=n;++i) cout<<i<<" "<<id[i]<<" "<<find(id[i])<<"!!\n";
	for(int i=1,x,y,l,r;i<=m;i++){
		x=read();y=read();
		l=find(id[x]);
		r=find(id[y]);
		//cout<<id[x]<<" "<<id[y]<<" "<<l<<" "<<r<<"!!\n";
		split(root,r,x,y);
		split(x,l-1,x,z); //x->z->y
		root=merge(merge(x,y),z); 
    }
    for(int i=n,node;i>=1;--i){
		split(root,i,x,y);
		node=x;
		while(rs(node)) node=rs(node);	
		printf("%lld",val(node));
		if(i==1) putchar('\n');
		else putchar(' ');
		root=merge(x,y);
	}
}

signed main(){
	srand(time(0));
//	ios::sync_with_stdio(0);
//	cin.tie(0);cout.tie(0);
//  freopen("in.cpp","r",stdin);
//  freopen("out.cpp","w",stdout);
	int T=1;
//	cin>>T;
//	clock_t start,finish;
//	start=clock();
	while(T--){
		Solve();
	}
//	finish=clock();
//	cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl;	return 0;
}

「2022 远光杯」双端队列
如题目所说,直接用双端队列模拟一下这个过程即可。

//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
//#define inf 0x3f3f3f3f
//#define int long long
using namespace std;
const int N=2e6+7;
const int mod=1e9+7;

//int read(){	int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
//void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}

int n,a[N],pos[N];
deque<int>dq;

void Solve(){
	cin>>n;
	for(int i=1;i<=n;++i) cin>>a[i],pos[a[i]]=i;
	while(dq.size()) dq.pop_front();
	dq.push_back(1);
//	lf=rg=1;
	for(int i=2;i<=n;++i){
		if(pos[i]<pos[i-1]) dq.push_front(i);
		else dq.push_back(i);
	}
	for(int i=1;i<=n;++i){
		if(a[i]!=dq.front()){
			cout<<"NO\n";
			return;			
		}
		dq.pop_front();
	}
	cout<<"YES\n";
	/*
	while(dq.size()){
		cout<<dq.front()<<" ";
		dq.pop_front();
	}*/
}

signed main(){
//	ios::sync_with_stdio(0);
//	cin.tie(0);cout.tie(0);
//  freopen("in.cpp","r",stdin);
//  freopen("out.cpp","w",stdout);
	int T=1;
	cin>>T;
//	clock_t start,finish;
//	start=clock();
	while(T--){
		Solve();
	}
//	finish=clock();
//	cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl;	return 0;
}

「2022 远光杯」旋转升天

母线长度/爬升能力就是汽车运动的总时间,乘以线速度就是他的总路程。

//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define int long long
using namespace std;
const int N=2e5+7;
const int mod=1e9+7;

//int read(){	int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
//void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}
void Solve(){
	double h,r,s,v;
	cin>>h>>r>>s>>v;
	double mu=sqrt(h*h+r*r);
	double t=mu/s;
	double sum=t*v;
	printf("%.10lf\n",sum);
}

signed main(){
//	ios::sync_with_stdio(0);
//	cin.tie(0);cout.tie(0);
//  freopen("in.cpp","r",stdin);
//  freopen("out.cpp","w",stdout);
	int T=1;
	cin>>T;
//	clock_t start,finish;
//	start=clock();
	while(T--){
		Solve();
	}
//	finish=clock();
//	cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl;	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RWLinno

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值