2022 年辽宁省大学生程序设计竞赛 个人题解

这篇具有很好参考价值的文章主要介绍了2022 年辽宁省大学生程序设计竞赛 个人题解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


title : 2022 年辽宁省大学生程序设计竞赛
date : 2022-10-25
tags : ACM,练习记录
author : Linno


2022 年辽宁省大学生程序设计竞赛

题目链接:https://ac.nowcoder.com/acm/contest/43937

进度:10/13

质量比较差的场,后三题是错的,D题spj也是错的,其他nt题也多。

A-伟大奋斗

#include<bits/stdc++.h>
using namespace std;

signed main(){
	int n;
	cin>>n;
	int ans=n-(2022-73);
	cout<<ans<<"\n";
	return 0;
} 

B-可莉的五子棋

枚举每个点作为起点向下统计就行了。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1007;
int n,m,ans[5];
char mp[N][N];

int check(int x,int y,char ch){
	int res=0;
	if(y+4<=m&&mp[x][y+1]==ch&&mp[x][y+2]==ch&&mp[x][y+3]==ch&&mp[x][y+4]==ch) ++res;
	if(x+4<=n&&mp[x+1][y]==ch&&mp[x+2][y]==ch&&mp[x+3][y]==ch&&mp[x+4][y]==ch) ++res;
	if(x+4<=n&&y+4<=m&&mp[x+1][y+1]==ch&&mp[x+2][y+2]==ch&&mp[x+3][y+3]==ch&&mp[x+4][y+4]==ch) ++res;
	if(x-4>=1&&y+4<=m&&mp[x-1][y+1]==ch&&mp[x-2][y+2]==ch&&mp[x-3][y+3]==ch&&mp[x-4][y+4]==ch) ++res;
	return res;
}

signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;++i){
		for(int j=1;j<=m;++j){
			cin>>mp[i][j];
		}
	}
	for(int i=1;i<=n;++i){
		for(int j=1;j<=m;++j){
			ans[mp[i][j]-'0']+=check(i,j,mp[i][j]);
		}
	}
	cout<<ans[1]<<" "<<ans[2]<<"\n";
	return 0;
}

C-消除死域点

先默认1为根,处理树上的祖先、大小和深度信息,如何第二遍dfs统计答案,假设最开始不删边的答案是 a n s ans ans,在 x x x点与父亲之间删一条边,对答案减少的贡献是 f [ x ] f[x] f[x],那么答案就是 a n s − m a x ( f i ) ans-max(f_i) ansmax(fi),对于 f [ x ] f[x] f[x]可以考虑求向上 s i z e size size不超过 k k k的段,那么整一段切给 x x x显然是最优的,并且下面的答案也不会改变, f [ x ] f[x] f[x]就是这一段的深度差。

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+7;

int n,k,mx=0,sz[N],dep[N],fa[N][25];
vector<int>G[N];

void dfs(int x,int f){   //处理树上每个结点的信息 
	sz[x]=1;dep[x]=dep[f]+1;
	fa[x][0]=f;
	for(int i=1;i<=20;++i) fa[x][i]=fa[fa[x][i-1]][i-1]; 
	for(auto to:G[x]){
		if(to==f) continue;
		dfs(to,x);
		sz[x]+=sz[to];
	}
}

void dfs2(int x,int f){
	if(sz[f]-1>=k){  //如果f的子树大小大于k 
		int p=x;
		for(int i=20;i>=0;--i){   //从x出发向上找一段 
			if(fa[p][i]&&sz[fa[p][i]]-sz[x]<k+1) p=fa[p][i]; 
		}
		mx=max(mx,dep[x]-dep[p]); //以x为新根,这一段的结点对答案贡献删除 
	}
	for(auto to:G[x]){
		if(to==f) continue;
		dfs2(to,x);
	}
}

signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n>>k;
	for(int i=1,u,v;i<n;++i){
		cin>>u>>v;
		G[u].emplace_back(v);
		G[v].emplace_back(u);
	}
	dfs(1,0);
	int ans=0;
	for(int i=1;i<=n;++i){
		if(sz[i]-1>=k) ++ans;
	}
	dfs2(1,0);
	cout<<ans-mx<<"\n";
	return 0;
}

D-七圣召唤

假设有 n n n次抽卡机会和 m m m种卡

集齐 m m m张卡的期望抽取次数是 E ( m ) = ∑ i m m i E(m)=\sum_i^m{\frac{m}{i}} E(m)=imim,可以理解为 i m \frac{i}{m} mi的概率抽到第 i i i种,因此期望次数就是它的倒数。

n n n次的期望种数是 F ( n ) = F ( n − 1 ) + m − F ( n − 1 ) m F(n)=F(n-1)+\frac{m-F(n-1)}{m} F(n)=F(n1)+mmF(n1),可以理解为在 n − 1 n-1 n1抽期望为 x x x种的基础上,抽到新的一种的概率为 m − x m \frac{m-x}{m} mmx

#include<bits/stdc++.h>
using namespace std;
int n,m;

signed main(){
	cin>>n>>m;
	double ans1=0,ans2=0;
	for(int i=1;i<=m;++i) ans1+=double(m)/i;
	for(int i=1;i<=n;++i) ans2+=(m-ans2)/m;
	printf("%.8lf %.8lf\n",ans1,ans2);
	return 0;
}

E-病毒危机

直接暴力找交集就可以了。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+7;

int n,m,k,is[N],yes[N];

signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n>>m;
	cin>>k;for(int i=1,x;i<=k;++i) cin>>x,is[x]=1;
	for(int i=2;i<=n;++i){
		cin>>k;
		for(int j=1,x;j<=k;++j){
			cin>>x;
			if(is[x]) yes[i]=1;
		}
	}
	int ans=1;
	for(int i=1;i<=n;++i) if(yes[i]) ++ans;
	cout<<ans<<"\n"; 
	return 0;
}

F-互质

挺离谱的,一开始还以为随机乱搞,但是一个连续的范围怎么可能会有很多数跟一个 1 e 18 1e18 1e18的数互质,所以当然是直接找啦。

#include<bits/stdc++.h>
#define int long long 
using namespace std;

int n,T;

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

inline int gcd(int a,int b){
	return b?gcd(b,a%b):a;
}

void solve(){
	n=read();
	int L=(n+3)/4,R=n/2;
	for(int i=L;i<=min(R,L+25ll);++i){
		if(gcd(n,i)==1){
			write(i);putchar('\n');
			return;
		}
	}
	puts("-1");		

}

signed main(){
	T=read();
	while(T--){
		solve();
	} 
	return 0;
}

G-栈与公约数

单点修改、单点查询、区间修改、区间查询,所以是线段树裸题。

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+1;

inline int gcd(int a,int b){
	return b?gcd(b,a%b):a;
}

int n;
#define ls (p<<1)
#define rs (p<<1|1)
#define mid ((l+r)>>1)
int tr[N<<2],tg[N<<2];

void pushdown(int p,int l,int r){
	if(tg[p]){
		tr[ls]=tr[rs]=tg[ls]=tg[rs]=tg[p];
		tg[p]=0;
	}
}

void update(int p,int l,int r,int pos,int v){
	if(l==r){tr[p]=v;return;}
	pushdown(p,l,r);
	if(pos<=mid) update(ls,l,mid,pos,v); 	
	else update(rs,mid+1,r,pos,v);
	tr[p]=gcd(tr[ls],tr[rs]);
}

int query(int p,int l,int r,int pos){
	if(l==r) return tr[p];
	pushdown(p,l,r);
	if(pos<=mid) return query(ls,l,mid,pos);
	else return query(rs,mid+1,r,pos);
}

int query_gcd(int p,int l,int r,int ql,int qr){
	if(ql<=l&&r<=qr) return tr[p];
	pushdown(p,l,r);
	if(ql>mid) return query_gcd(rs,mid+1,r,ql,qr);
	else if(qr<=mid) return query_gcd(ls,l,mid,ql,qr);
	else return gcd(query_gcd(ls,l,mid,ql,qr),query_gcd(rs,mid+1,r,ql,qr));
}

void modify(int p,int l,int r,int ql,int qr,int v){
	if(ql<=l&&r<=qr){
		tg[p]=tr[p]=v;
		return;
	}
	pushdown(p,l,r);
	if(ql<=mid) modify(ls,l,mid,ql,qr,v);
	if(qr>mid) modify(rs,mid+1,r,ql,qr,v);
	tr[p]=gcd(tr[ls],tr[rs]);
}

signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n;
	int idx=0;
	for(int i=1,op,x,k;i<=n;++i){
		cin>>op;
		if(op==1){
			cin>>x;
			++idx;
			update(1,1,n,idx,x);
		}else if(op==2){
			update(1,1,n,idx,0);
			--idx;
		}else if(op==3){
			cout<<query(1,1,n,idx)<<"\n";
		}else{
			cin>>k;
			int md=query_gcd(1,1,n,idx-k+1,idx);
			modify(1,1,n,idx-k+1,idx,md);
		}
	}
	return 0;
}

I-图的分割

读懂了就可以直观感受到他要求一个最小/大生成树,因为克鲁斯卡尔枚举边的过程时,最后一条边保证是把图分成两块并且边权最大值最小的,符合题目要求。

#include<bits/stdc++.h>
using namespace std;
const int N=2e6+7;
struct E{
	int u,v,w,nxt;
	friend bool operator <(E A,E B){
		return A.w>B.w;
	}
}e[N];
int cnt=0,head[N];
inline void addedge(int u,int v,int w){
	e[++cnt]=(E){u,v,w,head[u]};head[u]=cnt;
}

int n,m,ans,num=0,fa[N];
inline int find(int x){
	return fa[x]==x?x:fa[x]=find(fa[x]); 
}

signed main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i) fa[i]=i;
	for(int i=1,u,v,w;i<=n;++i){
		scanf("%d%d%d",&u,&v,&w);
		addedge(u,v,w);
		addedge(v,u,w); 
	}
	stable_sort(e+1,e+1+cnt);
	for(int i=1;i<=cnt;++i){
		int fx=find(e[i].u),fy=find(e[i].v);
		if(fx!=fy){
			++num;
			fa[fx]=fy;
			if(num==n-1){ //剩下一个点没有合并 
				ans=e[i].w;
				break;
			}
		}
	}
	cout<<ans<<"\n";
	return 0;
}

K-俄罗斯方块

不难想,打表可以发现有解的条件是 n % 8 = = 7 ∣ ∣ n % 8 = = 0 n\%8==7||n\%8==0 n%8==7∣∣n%8==0,在纸上画一画就可以得到 7 ∗ 7 7*7 77的三角形、 8 ∗ 8 8*8 88的三角形的构造(下面代码有),那么把他们拼在一块就变成了 8 ∗ 8 8*8 88的正方形了,接下来就模拟一下堆积木的过程。

#include<bits/stdc++.h>
using namespace std;

int n,idx=0,mp[1005][1005]; 

int tri1[10][10]={
{1},
{1,1},
{1,2,2},
{3,2,2,4},
{3,3,4,4,4},
{3,5,6,6,6,7},
{5,5,5,6,7,7,7}
};

int tri2[10][10]={
{1},
{1,1},
{1,2,2},
{3,2,2,4},
{3,3,4,4,4},
{3,6,6,6,7,7},
{5,5,6,8,7,7,9},
{5,5,8,8,8,9,9,9}
};

int rct[10][10]={
{1,10,10,10,11,12,12,12},
{1,1,10,11,11,11,12,13},
{1,2,2,14,14,14,13,13},
{3,2,2,4,14,15,15,13},
{3,3,4,4,4,15,15,16},
{3,6,6,6,7,7,16,16},
{5,5,6,8,7,7,9,16},
{5,5,8,8,8,9,9,9}
};


signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n;
//	for(int i=1;i<=n;++i) frac[i]=frac[i-1]+i;
//	for(int i=1;i<=n;++i) cout<<i<<" "<<frac[i]<<" "<<frac[i]%4<<" !!\n";
	if(n%8!=7&&n%8!=0){
		cout<<"NO\n";
		return 0;
	}
	cout<<"YES\n";
	int sx=1,sy=1,idx=0;
	if(n%8==7){
		for(int i=0;i<7;++i){
			for(int j=0;j<=i;++j){
				mp[sx+i][sy+j]=tri1[i][j]+idx;
			}
		}
		idx+=7;sx=8;sy=1;
		for(;sx<n;sx+=8){
			for(sy=1;sy<=sx;sy+=8){
				for(int i=0;i<8;++i){
					for(int j=0;j<8;++j){
						mp[sx+i][sy+j]=rct[i][j]+idx;
					}
				}
				idx+=16;
			}
			for(int i=0;i<7;++i){
				for(int j=0;j<=i;++j){
					mp[sx+i+1][sy+j]=tri1[i][j]+idx;
				}
			}
			idx+=7;
		}
	}else{
		for(int i=0;i<8;++i){
			for(int j=0;j<=i;++j){
				mp[sx+i][sy+j]=tri2[i][j]+idx;
			}
		}
		idx+=9;sx=9;sy=1;
		for(;sx<n;sx+=8){
			for(sy=1;sy<sx;sy+=8){
				for(int i=0;i<8;++i){
					for(int j=0;j<8;++j){
						mp[sx+i][sy+j]=rct[i][j]+idx;
					}
				}
				idx+=16;
			}
			for(int i=0;i<8;++i){
				for(int j=0;j<=i;++j){
					mp[sx+i][sy+j]=tri2[i][j]+idx;
				}
			}
			idx+=9;
		}		
	}
	for(int i=1;i<=n;++i){
		for(int j=1;j<=i;++j){
			//printf("%2d ",mp[i][j]);
			cout<<mp[i][j]<<" ";
		}
		cout<<"\n";
	}
	return 0;
}

M-画画

贪心把同时不符合行和列的奇偶性的格子改掉,必然是最优的。文章来源地址https://www.toymoban.com/news/detail-400854.html

#include<bits/stdc++.h>
using namespace std;
const int N=1007;

int n,numx[N],numy[N];
char mp[N][N];

void solve(){
	cin>>n;
	for(int i=0;i<n;++i){
		for(int j=0;j<n;++j){
			mp[i][j]='1';
			++numx[i];++numy[j];
		}
	}
	for(int i=n-1;i>=0;--i){
		for(int j=n-1;j>=0;--j){
			if((numx[i]&1)!=(i&1)&&(numy[j]&1)!=(j&1)){
				--numx[i];--numy[j];
				mp[i][j]='0';
			}
		}
	}
	for(int i=0;i<n;++i){
		for(int j=0;j<n;++j){
			cout<<mp[i][j];
		}
		cout<<"\n";
	}
	for(int i=0;i<n;++i) numx[i]=numy[i]=0;
}

signed main(){
	int t;
	cin>>t;
	while(t--){
		solve();
	}
	return 0; 
}

到了这里,关于2022 年辽宁省大学生程序设计竞赛 个人题解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 2019湖南省大学生程序设计竞赛题解(D)

    很妙的类似区间dp, 我自己是想不到,本题解题思路来自学长的博客: 长沙橘子猫 题意 有一个长度为 n n n 的序列,你可以给每个位置填 0 ∼ 9 0sim9 0 ∼ 9 的一个数,有 m m m 个限制,每个限制 [ l i , r i ] [l_{i}, r_{i}] [ l i ​ , r i ​ ] 要求区间内的数相乘必须为 9 9 9 的倍数,问

    2023年04月15日
    浏览(63)
  • 2023 年第五届河南省 CCPC 大学生程序设计竞赛

    Problem A. 小水獭游河南 ∣ a ∣ ≤ ∣ Σ ∣ = 26 ,暴力枚举 a 判断 b 是否为是回文串即可,时间复杂度 O ( ∣ Σ ∣ ∣ s ∣ ) 。 |a| ≤ |Σ| = 26,暴力枚举 a 判断 b 是否为是回文串即可,时间复杂度 O(|Σ||s|)。 ∣ a ∣ ≤ ∣Σ∣ = 26 ,暴力枚举 a 判断 b 是否为是回文串即可,时间复

    2024年02月03日
    浏览(89)
  • 【超好懂的比赛题解】2021 年四川省大学生程序设计竞赛

    title : 2021 年四川省大学生程序设计竞赛 date : 2022-7-18 tags : ACM,练习记录 author : Linno 题目链接:https://codeforces.com/gym/103117 进度:11/13 切题顺序:AKMBDHLJ IF赛后补了,CG没看 A. Chuanpai 给定正整数 k,问有多少正整数对 (x, y) 满足 x + y = k 且 1 ≤ x ≤ y ≤ 6。 x 和 y 的可行范围很小,

    2024年02月05日
    浏览(42)
  • 大学生音乐社区微信小程序的设计与实现 毕业设计开题报告

     博主介绍 :《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程,免费 项目配有对应开发文档、开题报告、任务书、PPT、论文模版

    2024年02月05日
    浏览(52)
  • 案例116:基于微信小程序的大学生就业平台设计与实现

    文末获取源码 开发语言:Java 框架:SSM JDK版本:JDK1.8 数据库:mysql 5.7 开发软件:eclipse/myeclipse/idea Maven包:Maven3.5.4 小程序框架:uniapp 小程序开发软件:HBuilder X 小程序运行软件:微信开发者 目录 目录 前言 系统展示 微信端功能模块的实现 微信端登录界面 首页界面 招聘详

    2024年01月21日
    浏览(52)
  • 大学生心理健康服务微信小程序系统的设计与实现

    随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了大学生心理健康服务微信小程序系统的开发全过程。通过分析大学生心理健康服务微信小程序系统管理的不足,创建了一个计算机管理大学生心理健康服务微信小程序系统

    2024年02月21日
    浏览(55)
  • HNUCM信息科学与工程学院第五届大学生程序设计竞赛——正式赛

    签到题 简单dp,取前面第五天的3倍就行 这题被封了不记得什么题了 枚举然后判断回文就行了 简单dp,不能跳的位置置0 算是一个简单思维题吧,先考虑偶奇依次排列,然后发现可能会剩下偶数或者奇数。 如果剩下的是偶数,因为偶数不会影响前面的奇偶性,所以在末尾首先

    2024年02月08日
    浏览(50)
  • 基于微信小程序的高校大学生社团管理系统设计与实现

    💗博主介绍:✌全网粉丝10W+,CSDN全栈领域优质创作者,博客之星、掘金/知乎/华为云/阿里云等平台优质作者。 👇🏻 精彩专栏 推荐订阅👇🏻 计算机毕业设计精品项目案例(持续更新) 🌟 文末获取源码+数据库+文档 🌟 感兴趣的可以先收藏起来,还有大家在毕设选题,项

    2024年01月25日
    浏览(96)
  • 第 46 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(上海),签到题6题

    补题链接:https://codeforces.com/gym/103446 E.Strange Integers E. Strange Integers time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard output Given n integers A1,A2,⋯,An and a parameter k, you should choose some integers Ab1,Ab2,⋯,Abm(1≤b1b2⋯bm≤n) so that ∀1≤ij≤m,|Abi−Abj|≥k. Determine th

    2024年02月09日
    浏览(38)
  • 第五届湖北省大学生程序设计竞赛(HBCPC 2023)vp赛后补题

    思路: 数位dp,如果我们暴力的计算的状态的话,显然就是记录每个数字出现几次。但是显然这样难以发挥数位dp的记忆化功效,因为只有出现次数相同,你是什么数字,实际是无所谓的。所以我们尝试记录每个出现次数有多少个数字 尝试打表发现,结果只有1477种 所以,对

    2024年02月07日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包