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 個點,求距離原點最近的距離

直接代碼:

#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;
} 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章