2021年度训练联盟热身训练赛第七场 German Collegiate Programming Contest 2020

2021年度训练联盟热身训练赛第七场
German Collegiate Programming Contest 2020

Problem A: Adolescent Architecture

先将圆柱体的半径乘2得到直径,将所有的积木按照边长(直径)排序,从上到下遍历,如果是圆柱体,判断它上面的一个正方体的底面能否放得下(即判断圆是否大于正方形的外切圆,圆的半径应大于正方形边长的根号2倍),否则则不能搭出,输出impossible。

AC代码:

#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
#include <cmath>
using namespace std;
struct node
{
	string s;
	int l;
}p[105];
bool cmp(node a,node b)
{
	if(a.l!=b.l)
		return a.l<b.l;
	else
	{
		if(a.s=="cylinder")
			return true;
		return false;
	}
}
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>p[i].s>>p[i].l;
		if(p[i].s=="cylinder")
			p[i].l*=2;
	}
	sort(p,p+n,cmp);
	int flag=1;
	for(int i=1;i<n;i++)
	{
		if(p[i].s=="cylinder")
			if(p[i].l/sqrt(2)<p[i-1].l)
			{
				flag=0;
				break;
			}
	}
	if(flag==0)
		cout<<"impossible"<<endl;
	else
	{
		for(int i=0;i<n;i++)
		{
			if(p[i].s=="cylinder")
				cout<<"cylinder "<<p[i].l/2<<endl;
			else
				cout<<"cube "<<p[i].l<<endl;
		}
	}
	return 0;
}

Problem F: Flip Flow

翻转沙漏,按题意模拟即可,注意考虑是翻转了奇数次还是偶数次。

AC代码:

#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t,s,n,l,a[1005];
	cin>>t>>s>>n;
	l=s;
	for(int i=0;i<n;i++)
		cin>>a[i];
	a[n]=t;
	for(int i=1;i<=n;i++)
	{
		if(i%2==1)
		{
			if(a[i]-a[i-1]<l)
				l-=a[i]-a[i-1];
			else
				l=0;
		}
		else
		{
			if(a[i]-a[i-1]<s-l)
				l+=a[i]-a[i-1];
			else
				l=s;
		}
	}
	if(n%2==1)
		cout<<l<<endl;
	else
		cout<<s-l<<endl;
	return 0;
}

Problem K: Knightly Knowledge

用map分别记录纪念碑和普通教堂的横纵坐标,并记录每个普通教堂的具体位置。遍历这些横纵坐标,更新能够使得教堂升级的最大数量的值。注意如果有教堂处于两条直线交汇点,要减去重复计算的一次。

AC代码:

#include <iostream>
#include <cstdio>
#include <map>
using namespace std;
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int m,c,x,y;
	map<int,int> monx,mony,chux,chuy;//纪念碑横纵坐标、教堂横纵坐标 
	map<pair<int,int>,int> chup;//教堂位置 
	cin>>m>>c;
	for(int i=0;i<m;i++)
	{
		cin>>x>>y;
		monx[x]++;
		mony[y]++;
	}
	for(int i=0;i<c;i++)
	{
		cin>>x>>y;
		if(monx[x]>1||mony[y]>1) continue;
		chux[x]++;
		chuy[y]++;
		chup[{x,y}]=1;
	}
	map<int,int>::iterator it1,it2;
	int ans=0,posx=0,posy=0;
	for(it1=monx.begin();it1!=monx.end();it1++)
	{
		if(it1->second>1) continue;
		for(it2=mony.begin();it2!=mony.end();it2++)
		{
			if(it2->second>1) continue;
			int temp=chux[it1->first]+chuy[it2->first];
			if(chup[{it1->first,it2->first}]==1)
				temp--;
			if(temp>ans)
			{
				ans=temp;
				posx=it1->first;
				posy=it2->first;
			}
		}
	}
	cout<<posx<<" "<<posy<<endl<<ans<<endl;
	return 0;
}

Problem L: Lexicographical Lecturing

要求选取字符串中长度最小的一段,使其按照字典序排序与原字符串排序的结果仍保持相同。我们直接分别从头和尾开始尝试缩短字符串,时间复杂度是够的。最“暴力”的方式就可以解决了,其实也是一个贪心的思想。

AC代码:

#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int n,l;
	string s[505];
	cin>>n>>l;
	for(int i=0;i<n;i++)
		cin>>s[i];
	int left=0;
	while(1)
	{
		int flag=1;
		for(int i=1;i<n;i++)
		{
			if(s[i].substr(left)<=s[i-1].substr(left))
			{
				flag=0;
				break;
			}
		}
		if(flag==0)
		{
			left--;
			break;
		}
		left++;
	}
	int len=l-left;
	while(1)
	{
		int flag=1;
		for(int i=1;i<n;i++)
		{
			if(s[i].substr(left,len)<=s[i-1].substr(left,len))
			{
				flag=0;
				break;
			}
		}
		if(flag==0)
		{
			len++;
			break;
		}
		len--;
	}
	cout<<left+1<<" "<<left+len<<endl;
	return 0;
}

Problem M: Mixtape Management

通过观察发现,答案要求的Windows系统下文件名排序就是按照数字大小升序排序。一种最简单的方式,我们直接将输入的每个数字输出即可。

AC代码:

#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int n,t;
	cin>>n;
	cin>>t;
	cout<<t;
	for(int i=1;i<n;i++)
	{
		cin>>t;
		cout<<" "<<t;
	}
	cout<<endl;
	return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

球王武磊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值