2020 年 “联想杯”全国高校程序设计在线邀请赛暨第三届上海理工大学程序设计竞赛(5.30)

A题链接

题目大意:一个大法师最多有为 n魔法值 ,他拥有两个技能:

1.每秒可以花费 x魔法值 释放一次技能

2.每秒 会自动恢复 y 魔法值,但是不能超过n,如果在恢复之前有p点法力,则法力将变为min(p + y,n)

问 m 秒内能最多放几次技能

解题思路:如果  y>x  ,那么每一秒都可以释放技能的,即  m  次

                  反之 ,y<x  ,那么(m-1)内恢复的魔法值 都会被用来释放技能 ,次数也就是

               (n+(m-1)*y)/x

                 直接两者取最小就好啦!

错误代码(憨憨的我直接暴力了,,5555当然超时了

#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
const int maxn=1e7;
int main()
{
	long long n,m,x,y,ans,t,k;
	cin>>t;
	while(t--)
	{
		ans=0;
		cin>>n>>m>>x>>y;
		k=n;
		while(m--)
		{
			if(n<x)
			{
				n=min(n+y,k);
				//cout<<"n::"<<n<<endl;
			}
			else
			{
				n-=x;
				//cout<<"n:"<<n<<endl;
				n=min(n+y,k);
			//	cout<<"n:"<<n<<endl;
				ans++; 
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

正确代码:

#include<iostream>
using namespace std;
int main()
{
	long long n,m,x,y,ans,t,k;
	cin>>t;
	while(t--)
	{
		ans=0;
		cin>>n>>m>>x>>y;
		k=min((n+(m-1)*y)/x,m);
		cout<<k<<endl;
	}
	return 0;
} 

B题链接

题目大意: 在三维直角坐标系内给出 n 个点,求距离原点最近的距离

扫描二维码关注公众号,回复: 11936837 查看本文章

直接代码:

#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
const int maxn=1e7;
int main()
{
	double d,x,y,z,minx;
	int n;
	cin>>n;
	minx=maxn;
	while(n--)
	{
		cin>>x>>y>>z;
		d=sqrt(x*x+y*y+z*z);
	//	cout<<d<<endl;
		minx=min(d,minx);
	}
	printf("%.3lf\n",minx);
	return 0;
}

C题链接

题目大意: 你有一张能最多写 n 个字符的纸,m 个可能重复的单词,你需要挑选一些不重复的写到纸上,单词之间必须用空格分隔(空格占一个字符),问最多能写下几个不同的单词

解题思路:先用map标记不重复的单词,再用数组装下它们的长度,ans用来表示所有不重复单词的长度和需要的空格,如果大于n了,就减去最长的那个单词和一个空格数,以此类推

代码:

#include<iostream>
#include<map>
#include<algorithm>
using namespace std;
map<string,int> mp;
int b[1010];
int main()
{
	string a;
	int n,m,i;
	cin>>n>>m;
	int ans=0;
	int k=0;
	int x=0;
	for(i=0;i<m;i++)
	{
		cin>>a;
		if(mp.count(a)==0)
		{
			k++;
			mp[a]++;
			b[k]=a.size();
			ans+=b[k];
		}
	}
	ans+=(k-1);
	if(n>=ans)
	{
		cout<<k<<endl;
		return 0;
	}
	sort(b+1,b+k+1);
	x=k;
	for(i=k;i>=1;i--)
	{
		ans-=b[i];
		ans-=1;
		x--;
		if(ans<=n)
		{
			break;
		}
	}
	
	cout<<x<<endl;
	//cout<<ans<<endl;
	return 0; 
} 

H题链接

题目大意:在n×m 的网格里,每个格子内的草每秒增加 a[ i ] [ j ],接下 来 k 个操作,每个操作会在某个时间把某一列或某一行的草割光, 求最终割掉的草的总和。

解题思路:找出每一行每一列最后被割的时间,分别为r[i]  ,c[i], 每个格子割掉的草等于

                (a[ i ][ j ] * max (r [ i ] , c [ j ] ) )

代码如下

#include<iostream>
using namespace std;
typedef long long ll;
const long long mod=998244353;
ll a[550][550];
ll r[550],c[550];
ll x,y,t;
int main()
{
	ll n,m,k,i,j;
	ll ans=0;
	char s;
	cin>>n>>m>>k;
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
		{
			cin>>a[i][j];
		}
	}
	for(i=1;i<=k;i++)
	{
		cin>>s;
		if(s=='r')
		{
			cin>>x>>t;
			r[x]=t;
		}
		if(s=='c')
		{
			cin>>y>>t;
			c[y]=t;
		}
	}
	ll num=0;
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
		{
			num=max(r[i],c[j]);
			num%=mod;
			a[i][j]%=mod;
			ans+=(a[i][j]*num)%mod;
			ans%=mod;
		}
	}
	cout<<ans%mod<<endl;
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/weixin_43819762/article/details/106448224