2022牛客寒假算法基础集训营1

比赛主页

 第A题(01背包dp)有一个数字根的结论

方法1:(不知道结论的,需要计算出数字根)

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<=n;i++)
typedef long long ll;
const int N = 1e5+8;
const int mod = 998244353;
ll t,n,m,a[N],sum[N],dp[N][10];
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		ll now = 0;
		if(a[i]>=10){
			while(a[i]>=10){//数字根
				now = 0;
				while(a[i]){
					now+=a[i]%10;
					a[i]/=10;
				}
				a[i]=now;
			}
			a[i]=now;
		}
	}
	dp[0][0]=1;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=9;j++){
			dp[i][j]=(dp[i][j]+dp[i-1][j])%mod;
			ll now = j+a[i];
			if(now>=10)now=1+now%10;
			dp[i][now]=(dp[i][now]+dp[i-1][j])%mod;
		}
		dp[i][a[i]]=(dp[i][a[i]]+1)%mod;
	}
	for(int i=1;i<=9;i++){
		cout<<dp[n][i]<<' ';
	}
	return 0;
}

方法2:

数字根结论:一个数的数字根等于这个数对9取模的结果(特殊的:取模为0的数字根为9) 

#include<bits/stdc++.h>
#define fors(i,a,b) for(int i = a; i < b; ++i)
#define ll long long
using namespace std;
const int maxn = 1e5+5;
int f[maxn][9];
const int mod = 998244353;
int main(){
	int n; cin>>n;
	f[0][0] = 1;
	fors(i,1,n+1){
		int x; scanf("%d", &x); x %= 9;
		fors(j,0,9){
			f[i][(j+x)%9] = (f[i][(j+x)%9] + f[i-1][j])%mod;
			f[i][j] = (f[i][j]+f[i-1][j])%mod;
		}
	}
	fors(i,1,9) cout<<f[n][i]<<" "; cout<<f[n][0]-1<<endl;
	return 0;
}

 第C题(难点在理解题意)模拟

#include<bits/stdc++.h>
using namespace std;
int main(){
	int a[105];
	int n;
	int ans=0;
	cin>>n;
	a[0]=0;
	for(int i=1;i<=n;i++){
		a[i]=a[i-1]+1;
		for(int j=1;j<=3;j++){
			int now;
			cin>>now;
			if(now==1){
				a[i]=max(a[i-j]+4,a[i]);
			}
		}
	}
	cout<<a[n]-n;
	return 0;
}

 第E题(想公式,模拟会超时)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1007;
int main()
{
	int t,n,m,ans;
	cin>>t;
	while(t--)
	{
		ans=0;
		cin>>n>>m;
		if(m==1)
		{
			if(n==1) cout<<"1"<<"\n";
			else cout<<"-1"<<"\n";
		}
		else
		{
			ans=((n-1)/(m-1)+((n-1)%(m-1)!=0))*2-1;
			cout<<ans<<"\n";
		}
	}
	return 0;
}
/*
把n个东西 每次减少m个 减少多少次能变成0
公式:n/m+(n%m!=0)
*/

第J题 (涉及前缀和,结构体等等)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+15;
ll va[N],vb[N];
bool cmp(int xx,int yy)
{
	return xx>yy;
}
int suma[N],sumb[N];
int main()
{
	int T,A,B,n;
	cin>>T;
	while(T--)
	{
		cin>>A>>B>>n;
		for(int i=1;i<=A;++i)
		{
			cin>>va[i];
		}
		for(int i=1;i<=B;++i)
		{
			cin>>vb[i];
		}
		int mxb=min(n/2,B);//为后面的数量判断准备
		if(A+mxb<n)//特判不合题意的
		{
			cout<<"-1"<<"\n";
			continue;
		}
		sort(va+1,va+1+A,cmp);
		sort(vb+1,vb+1+B,cmp);
		for(int i=1;i<=A;++i)
		{
			suma[i]=suma[i-1]+va[i];//前缀和
		}
		for(int i=1;i<=B;++i)
		{
			sumb[i]=sumb[i-1]+vb[i];
		}
		int ans=-1;
		for(int i=0;i<=A;++i)
		{
			int j=n-i;
			if(j>mxb||j<0) continue;
			ans=max(ans,suma[i]+sumb[j]);
		}
		cout<<ans<<"\n";
	}
	return 0;
}

 第L题(签到题):

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1007;
char a[N];
int main()
{
	double n,m;
	double ans,x,y;
	scanf("%lf",&n);
	while(n--)
	{
		x=0;
		y=0;
		ans=0;
		scanf("%lf",&m);
		scanf("%s",a);
		for(int i=0;i<m;++i)
		{
			if(a[i]=='U')
			{
				y+=1;
			}
			if(a[i]=='D')
			{
				y-=1;
			}
			if(a[i]=='R')
			{
				x+=1;
			}
			if(a[i]=='L')
			{
				x-=1;
			}
			double len;
			len=pow(x,2)+pow(y,2);
			len=sqrt(len);
			if(ans<len)
			{
				ans=len;
			}
		}
		printf("%.10lf\n",ans);
	}

	
	
	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值