中南大学第十二届大学生程序设计竞赛(网络同步赛)题解

CSU 2079

水题

CSU 2080

题意:看样例找规律,水题

#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1e6;
char s[maxn];
int main()
{
	while(~scanf("%s",s))
	{
		int len=strlen(s);
		for(int i=0;i<len;i++)
		{
			if((s[i]>='a'&&s[i]<='k')||s[i]>='A'&&s[i]<='K')
			printf("%c",s[i]+15);
			else if((s[i]>'k'&&s[i]<='z')||s[i]>'K'&&s[i]<='Z')
			printf("%c",s[i]-11);
			else 
			{
				if(s[i]=='}')
				printf(".");
				else if(s[i]=='(')
				printf(",");
				else
				printf(" ");
			}
		}
		printf("\n");
	}
}

F CSU 2084

题意:有n个面包和m瓶牛奶,每个面包有ai个分值,每瓶牛奶有bi个分值,要求吃完min(n,m)个牛奶和面包,每吃一个面包和一瓶牛奶可获得分ai*bi,求最大得分和最小得分。

思路:将a,b数组按照升序排序,设k=max(n,m)-min(n,m),假设n>m,最大得分求法就是ak+1*b1+ak+2*b2+...an*bm,最小得分求法是 a1*bm+a2*bm-1+...+am*b1。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e5+10;
int a[maxn],b[maxn];
int main()
{
	int n,m;
	while(~scanf("%d%d",&n,&m))
	{
		int i;
		for(i=1;i<=n;i++)
		scanf("%d",&a[i]);
		for(i=1;i<=m;i++)
		scanf("%d",&b[i]);
		sort(a+1,a+n+1);
		sort(b+1,b+m+1);
		int k=min(n,m);
		int ans1=0;
		int ans2=0;
		int t=max(n,m)-k;
		if(k==n)
		{
			for(i=1;i<=n;i++)
			{
				ans1+=a[i]*b[i+t];	
				ans2+=b[i]*a[n-i+1];
			}
		}
		else
		{
			for(i=1;i<=m;i++)
			{
				ans1+=a[i+t]*b[i];
				ans2+=a[i]*b[m-i+1];
			}
		}
		printf("%d %d\n",ans1,ans2);
	}
}

G CSU 2085

思路:求注册时间到现在时间有多少天就可以了,有坑的是题目给的在线时间单位是分钟,还有欧皇输出的是大写字母O不是0。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int b[13],sum;
void init()
{
	b[0]=a[0];
	for(int i=1;i<=12;i++)
	b[i]=b[i-1]+a[i];
}
void work(int year,int month,int day)//复杂度很高,但是可以接受,主要这样算天数思路清晰容易写 
{
	sum++;
	if(year==2018&&month==4&&day==22)
	return;
	if(day<a[month]||(year%4==0&&month==2&&day==28))
	{
		work(year,month,day+1);
	}
	else if(month<12)
	work(year,month+1,1);
	else
	work(year+1,1,1);
}
int main()
{
	int T;
	init();
	scanf("%d",&T);
	while(T--)
	{
		int year,month,day;
		int money,time;
		char s[50];
		scanf("%s%d%d",s,&money,&time);
		year=(s[0]-'0')*1000+(s[1]-'0')*100+(s[2]-'0')*10+s[3]-'0';
		month=(s[5]-'0')*10+s[6]-'0';
		day=(s[8]-'0')*10+s[9]-'0';
		sum=0;
		work(year,month,day);
		int t=sum;
		//printf("t=%d\n",t);
		int flag1,flag2;
		flag1=flag2=0;
		if(100*t<=money)
		flag1=1;
		if(12*t*60<=time)
		flag2=1;
		if((flag1+flag2)==0)
		printf("O\n");
		else if((flag1+flag2)==2)
		printf("GH\n");
		else
		{
			if(flag1==1)
			printf("H\n");
			else
			printf("G\n");
		}
	}
}

I CSU 2087

题意:给出一个字符串,由大写字母和'_'组成,其中'_'是让你填大写字母的,规定 A E I O U为原因字母,其他为辅音字母,该字符串不能出现连续三个元音字母或者连续三个辅音字母,且该字符串至少要有一个L。

思路:可以把元音字母简化为1,辅音字母简化为0,'_'看成是-1,-1可填1或0,直接对着-1 dfs,当dfs到最后一个时,判断是否满足连续三个数相加不能为3或0,设res为这次情况总数,满足条件就把ans+=res,种类数求法:设x为1的个数,y为0的个数,如果原串有L,res=5的x次方*21的y次方,如果原串没有L,res=5的x次方*(21的y次方-20的y次方)

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
char s[105];
int cnt[105],flag,n,tot;
long long ans;
void work(int t[105])
{
	for(int i=1;i<n-1;i++)
	{
		int tmp=t[i]+t[i-1]+t[i+1];
		if(tmp==3||tmp==0)
		return;
	}
	int vis=0;
	long long res=1;
	for(int i=1;i<=tot;i++)
	{
		int tmp=cnt[i];
		if(t[tmp]==0)
		vis++;
		else
		res*=5;
	}
	if(flag)
	{
		res*=pow(21,vis);
		ans+=res;	
	}

	else
	{
		if(vis)
		{
			res*=(pow(21,vis)-pow(20,vis));
			ans+=res;
		}
	}
}
void dfs(int k,int t[105])
{
	if(k>tot)
	{
		work(t);
		return;
	}
	int tmp=cnt[k];
	t[tmp]=0;
	dfs(k+1,t);
	t[tmp]=1;
	dfs(k+1,t);
}
int main()
{
	while(~scanf("%s",s))
	{
		int i,len=strlen(s);
		int t[105];
		flag=tot=0;
		n=len;
		for(i=0;i<len;i++)
		{
			if(s[i]=='L')
			flag=1;
			if(s[i]=='_')
			{
				cnt[++tot]=i;//记录要填字母的下标	
				t[i]=-1;
			}
			else if(s[i]=='A'||s[i]=='E'||s[i]=='I'||s[i]=='O'||s[i]=='U')
			t[i]=1;
			else
			t[i]=0;
		}	
		ans=0;
		dfs(1,t);
		printf("%lld\n",ans);
	}
}

J CSU 2088

题意:给两个点坐标和两个点的运动速度,在不限制时间的情况下求这两个点的最小距离

思路:其实这个题是个合格的高中数学题,设函数y为两点的距离,x为时间。


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const double f=1e-14;
int main()
{
	int T;
	scanf("%d",&T);
	int kase=0;
	while(T--)
	{
		double x1,y1,x2,y2,u1,v1,u2,v2;
		scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
		scanf("%lf%lf%lf%lf",&u1,&v1,&u2,&v2);
		double a=(u2-u1)*(u2-u1)+(v2-v1)*(v2-v1)+f;
		double b=2*((x2-x1)*(u2-u1)+(y2-y1)*(v2-v1))+f;
		double c=(x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+f;
		double ans;
		if(b>0)
		{
			ans=c+f;
		}
		else
		{
			ans=a*4*c-b*b+f;
			ans=ans/(a*4)+f;			
		}
		if(ans<=0)
		{
			printf("Case %d: 0.000000\n",++kase);
			continue;
		}
		ans=sqrt(ans);
		printf("Case %d: %.6lf\n",++kase,ans);
	}
}

猜你喜欢

转载自blog.csdn.net/ccsu_cat/article/details/80643438