第20届上海大学程序设计联赛夏季赛(校外同步赛)(部分题解)

比赛链接:第20届上海大学程序设计联赛夏季赛(校外同步赛

A中奖:

结构体排序即可:

struct elemt{
	int a,b,c;
	bool operator<(const elemt v){
		if(c==v.c){
			if(a==v.a){
				return b<v.b;
			}
			return a<v.a;
		}
		return c>v.c;
	}
};
elemt a[N];
int main(){
/*cout<<setiosflags(ios::fixed)<<setprecision(8)<<ans<<endl;//输出ans(float)格式控制为8位小数(不含整数部分)*/
/*cout<<setprecision(8)<<ans<<endl;//输出ans(float)格式控制为8位小数(含整数部分)*/
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);//同步流
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i].a>>a[i].b>>a[i].c;
	}
	sort(a+1,a+n+1);
	for(int i=1;i<=m;i++){
		cout<<a[i].a<<" "<<a[i].b<<" "<<a[i].c<<endl;
	}
	return 0;
}

B构造一个简单的数列:

赛时没看时间限制以为时间限制是1s,觉得暴力不过去,一直在找规律(不知道哪出了问题这规律死活过不去emm)。。

于是一直wa

 

emm~

赛后才发现限时5s,

正解:因为题目找的是当前可选的最小的互质的数,所以实际上两个数离得很近,用下标和数组记录下当前查到哪和哪些被占用了即可(暴力)

bool vis[1000010];
int main(){
/*cout<<setiosflags(ios::fixed)<<setprecision(8)<<ans<<endl;//输出ans(float)格式控制为8位小数(不含整数部分)*/
/*cout<<setprecision(8)<<ans<<endl;//输出ans(float)格式控制为8位小数(含整数部分)*/
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);//同步流
	int t;
	cin>>t;
	while(t--){
		int a,n;
		cin>>a>>n;
		if(n==1){
			cout<<a<<endl;
			continue;
		}
		memset(vis,0,sizeof(vis));
		int idx=1;
		vis[a]=1;
		int pre=a;
		for(int i=2;i<=n;i++){
			while(vis[idx]){
				idx++;
			}
			if(__gcd(idx,pre)==1){
				pre=idx;
				idx++;
			}
			else{
				int tmp=idx;
				while(__gcd(tmp,pre)!=1||vis[tmp]){
					tmp++;
				}
				pre=tmp;
				vis[tmp]=1;
			}
		}
		cout<<pre<<endl;
	}
	return 0;
}

C同心的凸正多面球:

        五种情况都判断一下试试即可

double a[N],b[N];
int main(){
/*cout<<setiosflags(ios::fixed)<<setprecision(8)<<ans<<endl;//输出ans(float)格式控制为8位小数(不含整数部分)*/
/*cout<<setprecision(8)<<ans<<endl;//输出ans(float)格式控制为8位小数(含整数部分)*/
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);//同步流
	double aa,r;
    cin>>aa>>r;
    a[1]=sqrt(2.0)/4.0;b[1]=sqrt(6.0)/4.0;
    a[2]=sqrt(2.0)/2.0;b[2]=sqrt(3.0)/2.0;
    a[3]=1.0/2.0;b[3]=sqrt(2.0)/2.0;
    a[4]=(sqrt(5.0)+3.0)/4.0;b[4]=(sqrt(3.0)+sqrt(15.0))/4.0;
    a[5]=(sqrt(5.0)+1)/4.0;b[5]=sqrt(10+sqrt(5.0)*2)/4.0;
    int f=0;
    for(int i=1;i<=5;i++){
        if(aa*a[i]<=r&&aa*b[i]>=r){
			f=1;
		}
    }
    if(f){
		cout<<"YES"<<endl;
	}
    else{
		cout<<"NO"<<endl;
	}
	return 0;
}

E排列计数:

        找规律,可以发现答案恰好就是(2n!)/2

int main(){
/*cout<<setiosflags(ios::fixed)<<setprecision(8)<<ans<<endl;//输出ans(float)格式控制为8位小数(不含整数部分)*/
/*cout<<setprecision(8)<<ans<<endl;//输出ans(float)格式控制为8位小数(含整数部分)*/
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);//同步流
    ll n;
    cin>>n;
    ll ans=1;
    for(ll i=1;i<=2*n-1;i++){
        ans=ans*i%mod;
    }
    ans=ans*n%mod;
    cout<<ans<<endl;
    return 0;
}

F金玉其外矩阵:

         如果N不能被h整除,那么我们可以每隔h-1行放一行负数,其每个负数的绝对值恰好比h-1个正数的和大一即可,这样不管怎么取都能保证题目要求,注意要把每个正数的值取大点,因为每行负数对应h-1行正数,其和为负数,但因为N不能被h整除,所以最后一定会多出至少1行整数,这就需要满足这至少一行整数要大于前面的和,如果N能被h整除,再同理考虑M不能被w整除的情况,如果M也被w整除就无解

int main(){
/*cout<<setiosflags(ios::fixed)<<setprecision(8)<<ans<<endl;//输出ans(float)格式控制为8位小数(不含整数部分)*/
/*cout<<setprecision(8)<<ans<<endl;//输出ans(float)格式控制为8位小数(含整数部分)*/
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);//同步流
	int n,m,h,w;
	cin>>n>>m>>h>>w;
	if(n%h){
		cout<<"Y"<<endl;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				if(i%h==0){
					cout<<-10000*(h-1)-1<<" ";
				}
				else{
					cout<<10000<<" ";
				}
			}
			cout<<endl;
		}
	}
	else if(m%w){
		cout<<"Y"<<endl;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				if(j%w==0){
					cout<<-10000*(w-1)-1<<" ";
				}
				else{
					cout<<10000<<" ";
				}
			}
			cout<<endl;
		}
	}
	else{
		cout<<"N"<<endl;
	}
	return 0;
}

G登山小分队:

这数据量暴力都能过,对每个节点维护下有人经过的时间段,用vector存,dfs暴力合并每个儿子的情况即可(貌似有更简单的非暴力做法)

vector<int>e[N];
void add(int u,int v){
	e[u].emplace_back(v);
	e[v].emplace_back(u);
}
vector<int>l[N],r[N];
vector<int>rl,rr;
void push_in(int le,int ri){
	if(rr.size()){
		if(le<rl.back()){
			ri+=rr.back()-rl.back();
			rl.back()=le;
			rr.back()=ri;
		}
		else if(le<=rr.back()){
			rr.back()+=ri-le;
		}
		else{
			rl.emplace_back(le);
			rr.emplace_back(ri);
		}
	}
	else{
		rl.emplace_back(le);
		rr.emplace_back(ri);
	}
}
void merge(int x,int y){
	rl.clear();
	rr.clear();
	int lx=0,ly=0;
	for(int i=0;i<l[x].size();i++){
		l[x][i]++;
		r[x][i]++;
	}
	while(lx<l[x].size()&&ly<l[y].size()){
		if(l[x][lx]>r[y][ly]){
			push_in(l[y][ly],r[y][ly]);
			ly++;
		}
		else if(r[x][lx]<l[y][ly]){
			push_in(l[x][lx],r[x][lx]);
			lx++;
		}
		else{
			int tl=min(l[x][lx],l[y][ly]),tr=max(r[x][lx],r[y][ly]);
			tr+=min(r[x][lx],r[y][ly])-max(l[x][lx],l[y][ly]);
			push_in(tl,tr);
			lx++;
			ly++;
		}
	}
	while(lx<l[x].size()){
		push_in(l[x][lx],r[x][lx]);
		lx++;
	}
	while(ly<l[y].size()){
		push_in(l[y][ly],r[y][ly]);
		ly++;
	}
	l[y]=rl;
	r[y]=rr;
}
int ans=0;
void dfs(int x,int pre){
	if(e[x].size()==1&&x!=1){
		l[x].emplace_back(-1);
		r[x].emplace_back(0);
		return ;
	}
	for(int i=0;i<e[x].size();i++){
		int tmp=e[x][i];
		if(tmp==pre){
			continue;
		}
		dfs(tmp,x);
		if(x==1){
			ans=max(ans,r[tmp].back()+1);
			continue;
		}
		merge(tmp,x);
	}
}
int main(){
/*cout<<setiosflags(ios::fixed)<<setprecision(8)<<ans<<endl;//输出ans(float)格式控制为8位小数(不含整数部分)*/
/*cout<<setprecision(8)<<ans<<endl;//输出ans(float)格式控制为8位小数(含整数部分)*/
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);//同步流
	int n;
	cin>>n;
	for(int i=1;i<n;i++){
		int u,v;
		cin>>u>>v;
		add(u,v);
	}
	dfs(1,0);
	cout<<ans<<endl;
	return 0;
}

H拼接的字符串:

首位查找下最远能匹配多少个,看看加一起是否比拼接的字符串长即可

int main(){
/*cout<<setiosflags(ios::fixed)<<setprecision(8)<<ans<<endl;//输出ans(float)格式控制为8位小数(不含整数部分)*/
/*cout<<setprecision(8)<<ans<<endl;//输出ans(float)格式控制为8位小数(含整数部分)*/
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);//同步流
	string s1,s2;
	cin>>s1>>s2;
	int x=0,y=0;
	for(int i=0;i<min(s2.length(),s1.length());i++){
		if(s1[i]!=s2[i]){
			break;
		}
		x++;
	}
	int len1=s1.length(),len2=s2.length();
	for(int i=0;i<min(s2.length(),s1.length());i++){
		if(s1[len1-1-i]!=s2[len2-1-i]){
			break;
		}
		y++;
	}
	if(x+y>=s1.length()){
		cout<<"YES"<<endl;
	}
	else{
		cout<<"NO"<<endl;
	}
	return 0;
}

I没有字母的数:

这数据量预处理下用前缀数字查找即可

int pre[N];
int check(int k){
	while(k){
		if(k%16>9){
			return 0;
		}
		k/=16;
	}
	return 1;
}
int main(){
/*cout<<setiosflags(ios::fixed)<<setprecision(8)<<ans<<endl;//输出ans(float)格式控制为8位小数(不含整数部分)*/
/*cout<<setprecision(8)<<ans<<endl;//输出ans(float)格式控制为8位小数(含整数部分)*/
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);//同步流
	for(int i=1;i<=1e6;i++){
		pre[i]=pre[i-1]+check(i);
	}
	int t;
	cin>>t;
	while(t--){
		int l,r;
		cin>>l>>r;
		cout<<pre[r]-pre[l-1]<<endl;
	}
	return 0;
}

D和J没过就不讲了,www~

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
“中国东信杯”广西大学第四程序设计同步题解“中国东信杯”广西大学第四程序设计同步题解“中国东信杯”广西大学第四程序设计同步题解“中国东信杯”广西大学第四程序设计同步题解“中国东信杯”广西大学第四程序设计同步题解“中国东信杯”广西大学第四程序设计同步题解“中国东信杯”广西大学第四程序设计同步题解“中国东信杯”广西大学第四程序设计同步题解“中国东信杯”广西大学第四程序设计同步题解“中国东信杯”广西大学第四程序设计同步题解“中国东信杯”广西大学第四程序设计同步题解“中国东信杯”广西大学第四程序设计同步题解“中国东信杯”广西大学第四程序设计同步题解“中国东信杯”广西大学第四程序设计同步题解“中国东信杯”广西大学第四程序设计同步题解“中国东信杯”广西大学第四程序设计同步题解“中国东信杯”广西大学第四程序设计同步题解“中国东信杯”广西大学第四程序设计同步题解“中国东信杯”广西大学第四

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值