Codeforces Round #277.5 (Div. 2) 解题报告(A B C D)

本文解析了四道编程题目,包括排序算法实现、配对球问题解决、指定条件下的数构造以及图上的路径计数问题。每道题目都提供了详细的解题思路及完整的代码实现。

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

A. SwapSort

        思路:从大到小对每个位置,如果它上面的数不是当前最大的,就随便找一个最大的换过去。这题坑了我好久,没看到不用找最小swap次数。。。

#include<iostream>
#include<cmath>
#include<queue>
#include<vector>
#include<algorithm>
#include<string.h>
#include<cstdio>

using namespace std;

int a[3010];
int b[3010];

int main(){
	int n;
	while(cin>>n){
		for(int i=0;i<n;i++){
			cin>>a[i];
			b[i]=a[i];
		}
		sort(b,b+n);
		int ans=0;
		vector<int> swa;
		for(int i=n-1;i>0;i--){
			if(a[i]==b[i])continue;
			for(int j=0;j<i;j++){
				if(b[i]==a[j]){
					swap(a[i],a[j]);
					ans++;
					swa.push_back(j);
					swa.push_back(i);
					break;
				}
			}
		}
		cout<<ans<<endl;
		for(int i=0;i<ans;i++){
			cout<<swa[i*2]<<" "<<swa[i*2+1]<<endl;
		}
	}
	return 0;
}

B. BerSU Ball

        思路:先计数,然后扫一遍,把能配对的全配对了就行。

#include<iostream>
#include<cmath>
#include<queue>
#include<vector>
#include<algorithm>
#include<string.h>
#include<cstdio>

using namespace std;

int cntB[110];
int cntG[110];

int main(){
	int n,m;
	cin>>n;
	for(int i=0;i<n;i++){
		int t;
		cin>>t; cntB[t]++;
	}
	cin>>m;
	for(int i=0;i<m;i++){
		int t;
		cin>>t; cntG[t]++;
	}
	
	int ans=0;
	for(int i=1;i<=100;i++){
		while(cntB[i]&&cntG[i-1]){
			cntB[i]--;
			cntG[i-1]--;
			ans++;
		}
		while(cntB[i]&&cntG[i]){
			cntB[i]--;
			cntG[i]--;
			ans++;
		}
		while(cntB[i]&&cntG[i+1]){
			cntB[i]--;
			cntG[i+1]--;
			ans++;
		}
		
	}
	cout<<ans<<endl;
	return 0;
}


C. Given Length and Sum of Digits...

        思路:为了使数合法,先在最高位置1,然后暴力从低位/高位加数即可。需要特判一下和为0长度为1的情况。

#include<iostream>
#include<cmath>
#include<queue>
#include<vector>
#include<algorithm>
#include<string.h>
#include<cstdio>

using namespace std;

int ans1[110];
int ans2[110];

int main(){
	int m,s;
	while(cin>>m>>s){
		memset(ans1,0,sizeof(ans1));
		memset(ans2,0,sizeof(ans2));
		
		if(m==1&&s==0){
			cout<<"0 0"<<endl;
			continue;
		}
		
		ans1[1]=1;
		int tmp=s-1;
		for(int i=m;i>=1;i--){
			while(ans1[i]<9){
				if(tmp<=0)break;
				ans1[i]++;
				tmp--;
			}
			if(tmp<=0)break;
		}
		if(tmp!=0){
			cout<<-1;
		}else{
			for(int i=1;i<=m;i++){
				cout<<ans1[i];
			}
		}
		cout<<" ";
		ans2[1]=1;
		tmp=s-1;
		for(int i=1;i<=m;i++){
			while(ans2[i]<9){
				if(tmp<=0)break;
				ans2[i]++;
				tmp--;
			}
			if(tmp<=0)break;
		}
		if(tmp!=0){
			cout<<-1;
		}else{
			for(int i=1;i<=m;i++){
				cout<<ans2[i];
			}
		}
		cout<<endl;
	}
	return 0;
}


D. Unbearable Controversy of Being

        思路:枚举起点,走两步,记cnt[i]为某个起点两步走到i的方法数,结果加上cnt[i]*(cnt[i]-1)/2。注意走两步后不要回到起点。

#include<iostream>
#include<cmath>
#include<queue>
#include<vector>
#include<algorithm>
#include<string.h>
#include<cstdio>

using namespace std;

#define ll long long

vector<int> E[3010];
ll cnt[3010];


int main(){
	int n,m;
	while(cin>>n>>m){
		for(int i=1;i<=m;i++){
			int u,v;
			scanf("%d%d",&u,&v);
			E[u].push_back(v);
		}
		
		ll ans=0;
		for(int k=1;k<=n;k++){
			memset(cnt,0,sizeof(cnt));
			
			queue<int> que;
			int siz=E[k].size();
			for(int i=0;i<siz;i++){
				que.push(E[k][i]);
			}
			while(!que.empty()){
				int cur=que.front();	que.pop();
				int siz=E[cur].size();
				for(int i=0;i<siz;i++){	
					if(E[cur][i]!=k)cnt[E[cur][i]]++;
				}
			}
			
			for(int i=1;i<=n;i++){
				if(cnt[i]>1){
					ans+=cnt[i]*(cnt[i]-1)/2;
				}
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值