2020上海高校程序设计竞赛暨第18届上海大学程序设计联赛夏季赛(同步赛)

A 同源

在这里插入图片描述
思路:

m=n/k后将m分成最大公因子为1的三个数,再将三个数分别乘以k即可得到a,b,c

/*
* problem:同源
* method:模拟、gcd
* date:2020/08/05
*/
#include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<utility>
#include<cmath>
#define ll long long
ll n,k,T,flag,a,b,c;
using namespace std;
ll gcd(ll a,ll b){
	while(b){
		ll c=a%b;
		a=b;
		b=c;
	}
	return a;
}
int fact(ll m) {
	ll i,j,k;
	for(i=2; i<=m/3; i++) {
		if((i%2==0)&&((m-i)%2)) continue;//偶+奇不行
		for(j=i+1;j<m/2;j++){
			if(gcd(i,j)==1){
				k=m-i-j;
				if(k<0) break;
				if(gcd(i,k)==1&&gcd(j,k)==1){
					//cout<<i<<" "<<j<<" "<<k<<endl;
					a=i;b=j;c=k;
					return 1;
				}
				
			}
		}
	}
	return 0;
}
int main() {
	cin>>T;
	while(T--) {
		cin>>n>>k;
		flag=1;
		if(n%k) {
			flag=0;
		} else {
			ll m=n/k;
			if(m<10) flag=0;
			else {
				flag=fact(m);
				a*=k;
				b*=k;
				c*=k;
			}
		}
		if(flag) cout<<a<<' '<<b<<' '<<c<<endl;
		else cout<<"-1 -1 -1"<<endl;
	}
	return 0;
}

B 分子

在这里插入图片描述
思路:

flag记录是否在括号内,在括号内的话将括号内C、H、O个数存入temp数组,否则自增总的num数组;
last记录上个字符,便于遍历到数字字符时加上响应的个数;

/*
* problem:分子
* method:字符串提取表达式
* date:2020/08/05
*/
#include<iostream>
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<utility>
#include<cmath>
#define ll long long
using namespace std;
ll num[3]={0};
ll weight[]={13,1,17};
string s;
int main(){
	int i,j,k;
	cin>>s;
	int flag=0;
	ll temp[3]={0};
	int last=-1;
	for(i=0;i<s.size();i++){
		char c=s[i];
		if(c=='('){
			flag=1;
			for(j=0;j<3;j++){
				temp[j]=0;
			}
			last=3;
		}else if(c=='C'){
			if(flag) temp[0]++;
			else num[0]++;
			last=0;
		}else if(c=='H'){
			if(flag) temp[1]++;
			else num[1]++;
			last=1;
		}else if(c=='O'){
			if(flag) temp[2]++;
			else num[2]++;
			last=2;
		}else if(c==')'){
			flag=0;
			last=4;
			if(s[i+1]<'0'||s[i+1]>'9'){
				for(j=0;j<3;j++){
					num[j]+=temp[j];
				}
			}
		}else{
			ll cnt=1,res=0;
			while(s[i]>='0'&&s[i]<='9'){
				int x=s[i]-'0';
				res*=10;
				res+=x;
				i++;
			}
			i--;
			//cout<<res<<endl;
			if(last==4){
				for(j=0;j<3;j++){
					num[j]+=temp[j]*res;
				}
			}else if(last>-1&&last<3){
				if(flag){
					temp[last]=temp[last]+res-1;
				} 
				else num[last]=num[last]+res-1;
			}
		}
	}
	ll res=0;
	for(i=0;i<3;i++){
		res+=num[i]*weight[i];
	}
	cout<<res<<endl;
	return 0;
}

C 爵士

在这里插入图片描述
思路:

模拟

/*
* problem:游戏
* method:规律、签到
* date:2020/08/05
*/
/*
* problem:爵士
* method:模拟
* date:2020/08/05
*/
#include<iostream>
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<utility>
#include<cmath>
#define ll long long
using namespace std;
int T,n;
string s;
int main(){
	int i,j,k;
	cin>>T;
	while(T--){
		cin>>n;
		getchar();
		double cnt=0,res;
		for(i=0;i<n;i++){
			getline(cin,s);
			//cout<<"s:"<<s<<endl;
			for(j=0;j<s.size();j++){
				if(s[j]=='2'){
					cnt++;
					break;
				}
			}
		}
		//cout<<cnt<<" "<<n<<endl;
		res=cnt/n;
		printf("%.10lf\n",res);
	}
	return 0;
}

F 游戏

在这里插入图片描述
思路

奇数个结点故不存在平局
每次Sparken先选,总是可以选择当前可收获的点,而下一次可获得的最多的点数总是不大于上一次最多可收获的点数,故Sparken必胜

/*
* problem:游戏
* method:规律、签到
* date:2020/08/05
*/
#include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<utility>
#include<cmath>
#define ll long long
using namespace std;
int T,n,u,v;
int main(){
	int i,j,k;
	cin>>T;
	while(T--){
		cin>>n;
		for(i=0;i<n-1;i++){
			cin>>u>>v;
		}
		cout<<"Yes"<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/The_Only_God/article/details/107825273
今日推荐