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

本文深入探讨了编程领域的核心技术,包括前端、后端、移动开发、游戏开发、大数据、开发工具等多个细分领域。从核心概念、关键技术到实际应用案例,为您呈现全面的技术洞察。

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

A. Team Olympiad


        思路:给1,2,3计数,答案就是它们中的最小者。然后从数组里面取就可以了。


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

using namespace std;

int a[5010];
int cnt[4]={0};

int main(){
	int n;
	
	while(cin>>n){
		for(int i=1;i<=n;i++){
			cin>>a[i];
			cnt[a[i]]++;
		}
		int ans=min(cnt[1],cnt[2]);
		ans=min(cnt[3],ans);
		cout<<ans<<endl;
		while(ans--){
			int q,w,e;
			q=w=e=0;
			for(int i=1;i<=n;i++){
				if(a[i]==1&&q==0){
					q=i;
					a[i]=0;
				}
				if(a[i]==2&&w==0){
					w=i;
					a[i]=0;
				}
				if(a[i]==3&&e==0){
					e=i;
					a[i]=0;
				}
			}
			printf("%d %d %d\n",q,w,e);
		}
	}
	
	return 0;
}



B. Queue


        思路:建立一个向后的链和向前的链。用向后的链,从0开始扫一遍,可以得到排在偶数位的。然后随便找一个没出现过的号,用向前的链跟踪到头,就是排在第一位的,再用向后的链扫一遍,得到排在奇数位的。


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

using namespace std;

int data[1000010];	//向后 
int data2[1000010];	//向前 
bool has[1000010];
int que[200010];

int main(){
	int n;
	while(cin>>n){
		memset(data,-1,sizeof(data));
		memset(data2,-1,sizeof(data2));
		for(int i=1;i<=n;i++){
			int a,b;
			scanf("%d%d",&a,&b);
			data[a]=b;
			data2[b]=a;
			has[a]=1;
			has[b]=1;
		}
		has[0]=0;
		int tmp=0;
		int k=2;
		while(1){
			que[k]=data[tmp];
			has[que[k]]=0;
			k+=2;
			tmp=data[tmp];
			if(tmp<=0){
				break;
			}
		}
		
		//找一个没出现的 
		int fnd;
		for(int i=1;i<=1000000;i++){
			if(has[i]){
				fnd=i;
				break;
			}
		}
		
		//跟踪到头 
		tmp=fnd;
		while(1){
			if(data2[tmp]==-1)break;
			tmp=data2[tmp];
		}
		
		k=1;
		while(1){
			que[k]=tmp;
			tmp=data[tmp];
			k+=2;
			if(tmp<=0)break;
		}
		for(int i=1;i<=n;i++){
			printf("%d ",que[i]);
		}
	}
	return 0;
}


C. Hacking Cypher


        思路:大整数的整除判断肯定只能逐位来。如从左往右扫描,计算每位模a的结果,乘以10(因为是十进制)后往右叠加并取模,如果到某位模为0说明可以在该位分割。从右往左扫描的原理则是反过来,用一个变量表示当前位的大小,每次扩大10倍并取模(因为是十进制)往左叠加取模,如果模为0说明可以分割。如果某个地方左右都能分割,就是合法的,注意不能有前导零。


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

using namespace std;

char num[1000010];
bool ok[1000010];
int tmp [1000010];

int main(){
	while(~scanf("%s",num)){
		int siz=0;
		int a,b;
		cin>>a>>b;
		
		if(num[0]=='0'){
			cout<<"NO"<<endl;
			continue;
		}
		
		int len=strlen(num);
		int cur=0;
		for(int i=0;i<len;i++){
			cur*=10;
			cur+=num[i]-'0';
			cur%=a;
			if(cur==0){
				if(i<len-1&&num[i+1]!='0'){
					ok[i]=1;
				}
			}
		}
		
		bool hasans=0;
		int split;
		
		int k=1;
		cur=0;
		for(int i=len-1;i>=0;i--){
			cur+=(num[i]-'0')*k;
			cur%=b;
			if(cur==0&&ok[i-1]&&num[i]!='0'){
				hasans=1;
				split=i;
				break;
			}
			k*=10;
			k%=b;
		}
		
		if(hasans){
			cout<<"YES"<<endl;
			for(int i=0;i<split;i++){
				printf("%c",num[i]);
			}
			cout<<endl;
			for(int i=split;i<len;i++){
				printf("%c",num[i]);
			}
		}else{
			cout<<"NO"<<endl;
		}
	}
	return 0;
}


D. Chocolate


        思路:dfs。找到两块巧克力可以达到的状态,记录状态下需要的操作次数。最后扫描两块巧克力的状态集合,发现大小相等的,把操作次数相加并更新结果。其实这题可以用数学方法做的,效率更高。


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

using namespace std;

#define ll long long

struct node{
	ll a;
	ll b;
	int t;
	ll s; 
	node(ll aa,ll bb,int tt=0){
		a=aa; b=bb;
		t=tt;
		s=aa*bb;
	}
	
	bool operator<(const node& n2)const{
		if(s!=n2.s)return s<n2.s;
		return t<n2.t;
	}
};

set<node> s1;
set<node> s2;

void dfs(node n,int id){
	if(id==1){
		if(s1.count(n))return;
		s1.insert(n);
	}else{
		if(s2.count(n))return;
		s2.insert(n);
	}
	if(n.a%2==0){
		node q(n.a/2,n.b,n.t+1);
		dfs(q,id);
	}
	if(n.a%3==0){
		node q(n.a/3*2,n.b,n.t+1);
		dfs(q,id);
	}
	if(n.b%2==0){
		node q(n.a,n.b/2,n.t+1);
		dfs(q,id);
	}
	if(n.b%3==0){
		node q(n.a,n.b/3*2,n.t+1);
		dfs(q,id);
	}
}


int main(){
	int a1,b1,a2,b2;
	while(cin>>a1>>b1>>a2>>b2){
		node c1(a1,b1,0);
		node c2(a2,b2,0);
		
		dfs(c1,1);
		dfs(c2,2);
		
		int ans=10086;
		int ans1,ans2,ans3,ans4;
		for(set<node>::iterator it=s1.begin();it!=s1.end();it++){
			for(set<node>::iterator it2=s2.begin();it2!=s2.end();it2++){
				if(it->s==it2->s){
					if(it->t+it2->t<ans){
						ans=it->t+it2->t;
						ans1=it->a;
						ans2=it->b;
						ans3=it2->a;
						ans4=it2->b;
					}
				}
			}
		}
		if(ans!=10086){
			cout<<ans<<endl;
			cout<<ans1<<" "<<ans2<<endl;
			cout<<ans3<<" "<<ans4<<endl;
		}else{
			cout<<-1<<endl;
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值