“蔚来杯“2022牛客暑期多校训练营(加赛)补题

M  Maimai DX 2077

题意

有个音游叫 Maimai DX 2077。 这个音游有四种音符,每种音符有五个判定。 不同音符的不同判定会获得不同基础分数。 绝赞的判定单独计算分数。 给定一次游玩每种音符每种判定的数量,问达成度。

代码

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <deque>
#include <stdio.h>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <iomanip>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define int long long  
#define pii pair<int,int>
using namespace std;
int t[5],h[5],s[5],b[5];
double st=0,sh=0,ss=0,sb=0,e=0;
signed main()
{
	IOS;
	
	int i,j;
	cin>>t[0]>>t[1]>>t[2]>>t[3]>>t[4];
	cin>>h[0]>>h[1]>>h[2]>>h[3]>>h[4];
	cin>>s[0]>>s[1]>>s[2]>>s[3]>>s[4];
	cin>>b[0]>>b[1]>>b[2]>>b[3]>>b[4];
	
	st=((t[0]+t[1])*1.0+t[2]*0.8+t[3]*0.5);
	sh=((h[0]+h[1])*2.0+h[2]*1.6+h[3]*1.0);
	ss=((s[0]+s[1])*3.0+s[2]*2.4+s[3]*1.5);
	sb=((b[0]+b[1])*5.0+b[2]*2.5+b[3]*2.0);
	
	e=b[0]*1.0+b[1]*0.5+b[2]*0.4+b[3]*0.3;
	double a0=st+sh+ss+sb;
	double b0=e;
	
	double a=0,bb=0;
	a=(t[0]+t[1]+t[2]+t[3]+t[4])*1.0
		+(h[0]+h[1]+h[2]+h[3]+h[4])*2.0
		+(s[0]+s[1]+s[2]+s[3]+s[4])*3.0
		+(b[0]+b[1]+b[2]+b[3]+b[4])*5.0;
	bb=(b[0]+b[1]+b[2]+b[3]+b[4])*1.0;
	cout<<fixed<<setprecision(9)<<100.0*a0/a+b0/bb<<endl;
	
	
	
	return 0; 
}

E  Everyone is bot

题意

有 n 个人打算在群里复读。 一次复读的过程如下: 每一轮,n 个人按照编号从小到大依次执行以下操作。 如果这个人在前几轮已经进行过复读,他不会再次复读。也就是说,每个人最多只会复读一次。 否则他可以选择是否进行复读。 如果某一轮没有人进行复读,那么复读的过程结束。 对于第 i 个人,如果他是所有人中第 j 个进行复读的,他会获得 ai,j 瓶冰红茶。但是如果他是所有进行了复读的人当中倒数第 p 个进行复读的人,那么他不会获得任何冰红茶,并且需要交给咩噗特雷格博154 瓶冰红茶 (即获得 −154 杯冰红茶)。 每个人都想最大化自己获得的冰红茶数量,求所有人一共会拿到多少冰红茶。

思路

总复读人数是nmodp。因为每个人都想获得冰红茶,所以只要他不处于倒数第p个,他就会参与复读。从后往前思考,如果当前已经有n−p个人复读了,那么不会有人愿意成为倒数第p个,所以后面不会有任何人复读。如果当前已有n-2p个人复读了,那么不会有人愿意成为倒数第2p个,因为在他之后必然有人接着复读,当达到n-p时必定没有人愿意复读,此时他便会上交154瓶冰红茶。由此可见,如果当前复读人数是n−kp那么后面不会有人复读。因而只会有前nmodp个人复读。

代码

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <deque>
#include <stdio.h>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <iomanip>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define int long long  
#define pii pair<int,int>
using namespace std;
int a[1005][1005];
signed main()
{
    IOS;
     
    int n,p;
    cin>>n>>p;
    int i,j;
    for(i=1;i<=n;i++)
    {
    	for(j=1;j<=n;j++)
    	{
    		cin>>a[i][j];
		}
	}
	for(i=1;i<=n%p;i++)
	{
		cout<<a[i][i]<<" ";
	}
	for(;i<=n;i++)
	{
		cout<<"0 ";
	}
    
    
     
     
    return 0; 
}

H  Here is an Easy Problem of Zero-chan

题意

有一棵n个节点且以1为根的有根树。第i个点的点权为i。多次查询编号为 x 的点, ∏lca(i, x) 的末尾有多少个零。

思路

问题可以转变成为求它能分解出2和5的最小值作为因子。可以将点分为两类,对于处于x的子树内的点,与x的lca均为x;而不处于x的子树内的点,那么他们的lca均为x的祖先。所以对于查询x而言,可以枚举x到根节点的所有节点,对于每个点计算有多少个点与x不在同一个儿子子树内。对于点x,他的父亲节点fax对于祖先路径上的权值计算与x相同,所以可以采用树形dp来减少重复的计算。 则可以得到转移式dpx=dpfax+sizex×(cntx2|5−cntfax2|5),其中sizex代表 x 的子树大小,cntx2|5代表节点x能分解出多少个2或5。

代码

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <deque>
#include <stdio.h>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <iomanip>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define int long long  
#define pii pair<int,int>
using namespace std;
int n,q;
int u,v;
int x;
int dp5[100005],dp2[100005];//答案中2和5的个数 
int num2[100005],num5[100005];
vector<int>g[100005];
int er[100005];//子树的结点个数 
void dfs(int u,int fa)//求子树大小,即er[] 
{
	er[u]=1;
	for(auto i:g[u])
	{
		if(i==fa)
			continue;
		dfs(i,u);
		er[u]+=er[i];
	 } 
}
void dfs1(int u,int fa)
{
	dp2[u]=dp2[fa]+er[u]*(num2[u]-num2[fa]);
	dp5[u]=dp5[fa]+er[u]*(num5[u]-num5[fa]);
	for(auto i:g[u])
	{
		if(i==fa)
			continue;
		dfs1(i,u);
	}
}
signed main()
{
	IOS;
	
	cin>>n>>q;
	int i,j,k;
	for(i=1;i<=n;i++)
	{
		k=i;
		while(k%2==0)
		{
			num2[i]++;
			k/=2;
		}
		while(k%5==0)
		{
			num5[i]++;
			k/=5;
		}
	}
	for(i=1;i<n;i++)
	{
		cin>>u>>v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	dfs(1,0);
	dfs1(1,0);
	while(q--)
	{
		cin>>x;
		cout<<min(dp2[x],dp5[x])<<endl;
	}
	
	
	
	return 0;
} 
    
    
     
     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值