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

F 中位数切分

给定一个长为nnn的数组aaa和一个整数mmm,你需要将其切成连续的若干段,使得每一段的中位数都大于等于mmm,求最多可以划分成多少段。我们定义,偶数个数的中位数为中间两个数中较小的那一个,奇数个数的中位数就是正中间的数。如[2,3,1,5][2,3,1,5][2,3,1,5]的中位数为222,[2,3,1,2][2,3,1,2][2,3,1,2]的中位数为222,[3,5,9,7,11][3,5,9,7,11][3,5,9,7,11]的中位数为777。

输入描述:

输入第一行是一个整数T(1≤T≤20)T(1\leq T\leq 20)T(1≤T≤20),测试组数。

每个测试第一行是两个整数n,m(1≤n≤105,1≤m≤109)n,m(1\leq n\leq 10^5, 1\leq m \leq 10^9)n,m(1≤n≤105,1≤m≤109),含义如题目所示。

第二行输入nnn个数,数组aaa,满足1≤ai≤1091\leq a_i\leq 10^91≤ai​≤109。

由于本题输入量较大,建议使用scanf等高效输入方式。

输出描述:

每个测试用例,输出一个整数,表示最多可以划分成多少段,若无论如何划分都不能满足条件,输出−1-1−1。
#include<bits/stdc++.h>
using namespace std;
int main(){
	int t;
	cin>>t;
	while(t--){
		int n,m,x,ans=0;
		cin>>n>>m;
		for(int i=0;i<n;i++){
			cin>>x;
			if(x>=m)ans++;
			else ans--;
		}
		if(ans<=0)ans=-1; 
		cout<<ans<<endl;
	}
	return 0;
} 

A九小时九个人九扇门

在打越钢太郎的著名解谜游戏系列《极限脱出》的第一作《九小时九个人九扇门》中,有这样一个有趣的设定:游戏中,999位主人公被困在一座大型的豪华巨轮中,每个人手上都有一个奇怪的手表,手表上有一个数字,999个人的数字分别是1−91-91−9;在巨轮中,还有很多紧闭的数字门,每扇数字门上也有一个1−91-91−9的数字,要想打开数字门逃出生天,主角们必须要满足一个奇怪的条件:

kkk个人能够打开门上数字为ddd的一扇数字门,当且仅当这kkk个人的腕表数字之和的数字根恰好为ddd。

一个数字的数字根是指:将该数字各数位上的数字相加得到一个新的数,直到得到的数字小于101010为止,例如,149149149的数字根为149=>1+4+9=14=>1+4=5149 => 1+4+9=14 => 1+4=5 149=>1+4+9=14=>1+4=5,故149149149的数字根为5。我们约定,小于101010的数字,其数字根就为其本身。

例如,如果游戏中的一宫(手表数字为111)、四叶(手表数字为444)、八代(手表数字为888)三人组合在一起,就可以打开编号为444的数字门,这是因为1+4+8=131+4+8=131+4+8=13,而131313的数字根为444。

现在,你是游戏的主角,淳平,你知道船上包括自己在内的nnn个人的手表数字,为了分析局势,你想要计算出可以打开1−91-91−9号门的人物组合有多少种,你可以完成这项任务吗?

输入描述:

 

输入的第一行包含一个整数n(1≤n≤105)n(1\leq n \leq 10^{5})n(1≤n≤105),主人公的数量。

下面一行nnn个数,第iii个数字ai(1≤ai≤109)a_{i}(1\leq a_{i}\leq 10^{9})ai​(1≤ai​≤109)表示第iii位主人公的腕表数字。

输出描述:

 

你需要输出999个数字,第iii个数字表示有多少种不同的人物组合,可以打开编号为iii的数字门。

答案可能很大,请你将答案对998244353998244353998244353取模后输出。

示例1

输入

9
1 2 3 4 5 6 7 8 9

输出

56 56 58 56 56 58 56 56 59

 

#include<bits/stdc++.h>
using namespace std;
int dp[100005][10];
int main(){
	int n,m;
	cin>>n;
	dp[0][0]=1;
	for(int i=1;i<=n;i++){
		cin>>m;
		m%=9;
		for(int j=0;j<9;j++){
			dp[i][(j+m)%9]=(dp[i][(j+m)%9]+dp[i-1][j])%998244353;
			dp[i][j]=(dp[i][j]+dp[i-1][j])%998244353;
		}
	}
	for(int i=1;i<9;i++){
		cout<<dp[n][i]<<" ";
	}
	cout<<dp[n][0]-1<<endl;
	return 0;
} 

H牛牛看云

就像罗夏墨迹测试一样,同一片形状的云在不同人的眼中会看起来像各种各样不同的东西。

例如,现在天上飘过了一片长条状的云彩,hina说这片云长得像是薯条,moca说这片云长得像宾堡豆沙面包(5枚装),kasumi说这片云在闪闪发光,kokoro说这片云怎么看上去不开心呢,牛牛说这片云长得就像是:

Σi=1nΣj=in∣ai+aj−1000∣\Sigma_{i=1}^{n} \Sigma_{j=i}^{n} |a_i+a_j-1000|Σi=1n​Σj=in​∣ai​+aj​−1000∣

现在给出整数序列aaa,请你帮牛牛求出这个式子的值。

输入描述:

 

第一行包括一个整数n(3≤n≤106)n(3\leq n \leq 10^6)n(3≤n≤106),整数序列的长度。

第二行输入nnn个以空格分隔的整数ai(0≤ai≤1000)a_i(0\leq a_i \leq 1000)ai​(0≤ai​≤1000),表示序列aaa。

输出描述:

输出一个整数,表示该式子的值。

示例1

输入

4
500 501 500 499

输出

8

 

#include<bits/stdc++.h>
using namespace std;
int s[1000005];
long long sum1[1005];
int main(){
	int n,m;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>s[i];
		sum1[s[i]]++;
	}
	long long ans=0,num;
	for(int i=0;i<=1000;i++){
		for(int j=i;j<=1000;j++){
			if(i==j){
				num=(sum1[i]+sum1[i]*(sum1[i]-1)/2);
			}
			else{
				num=sum1[i]*sum1[j];
			}
			ans+=num*abs(i+j-1000);
		}
	}
	cout<<ans<<endl;
	return 0;
} 

CBaby's first attempt on CPU

#include<bits/stdc++.h>
using namespace std;
int s[105],a[105][5],sum1[1005];
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		s[i]=4;
		for(int j=1;j<=3;j++){
			cin>>a[i][j];
			if(a[i][j]){
				s[i]=min(s[i],j);
			}
		}
	}
	int j,ans;
	for(int i=1;i<=n;i++){
		if(s[i]!=4){
			j=ans;
			while(sum1[j]!=i-s[i]){
				j--;
			}
			int k=3-(ans-j);
			for(int j=1;j<=k;j++){
				sum1[++ans]=0;
			}	
		}
		sum1[++ans]=i;
	}
	cout<<ans-n<<endl;
	return 0;
} 

D牛牛做数论

#include<bits/stdc++.h>
using namespace std;
long long n;
long long s[20]={0,2,3,5,7,11,13,17,19,23,29,31,37,41};
int fun(int x){
	if(x<=3){
		return 1;	
	}
	for(int i=2;i*i<=n;i++){
		if(n%i==0){
			return 0;
		}
	}
	return 1;
}
int main(){
	int t;
	cin>>t;
	while(t--){
		cin>>n;
		long long ans=1,i=1;
		if(n==1){
			cout<<"-1"<<endl;
			continue;
		}
		while(1){
			if(ans*s[i]>n)break;
			ans*=s[i];
			i++;
		}
		cout<<ans<<" ";
		while(!fun(n))n--;
		cout<<n<<endl;
	}
	return 0;
} 

B炸鸡块君与FIFA22

#include<bits/stdc++.h>
using namespace std;
int fun(int x){
	return (x%3+3)%3;
}
int a[3][200005][21];
char s[200005];
int main(){
	int n,m;
	cin>>n>>m;
    scanf("%s",s+1);
    for(int j=0;j<=20;j++){
        for(int i=1;i<=n;i++){
            if(j==0){
                if(s[i]=='W'){
                    a[0][i][j]=a[1][i][j]=a[2][i][j]=1;
                }
                if(s[i]=='L'){
                    a[1][i][j]=a[2][i][j]=-1;
                    a[0][i][j]=0;
                }
                if(s[i]=='D'){
                    a[0][i][j]=a[1][i][j]=a[2][i][j]=0;
                }
            }
            else{
                int p1=i,p2=i+(1<<(j-1));
                if(p2>n){
                    a[0][p1][j]=a[0][p1][j-1];
                    a[1][p1][j]=a[1][p1][j-1];
                    a[2][p1][j]=a[2][p1][j-1];
                }
                else{
                    a[0][p1][j]=a[0][p1][j-1]+a[fun(0+a[0][p1][j-1])][p2][j-1];
                    a[1][p1][j]=a[1][p1][j-1]+a[fun(1+a[1][p1][j-1])][p2][j-1];
                    a[2][p1][j]=a[2][p1][j-1]+a[fun(2+a[2][p1][j-1])][p2][j-1];
                }
            }
        }
    }
    int l,r,ans;
    for(int k=1;k<=m;k++){
        cin>>l>>r>>ans;
        int num=l;
        while(num<=r){
            int j=0;
            while(num+(1<<j)-1<=r){
            	j++;	
			}
            j--;
            ans+=a[ans%3][num][j];
            num+=(1<<j);
        }
        cout<<ans<<endl;
    }
	return 0;
} 

DB站与各唱各的

#include<bits/stdc++.h>
using namespace std;
const int mod=1000000007;
int fun1(int x,int k) {
    int ans=1;
    while (k) {
        if (k&1) ans=ans*x%mod;
        x=x*x%mod;
        k>>=1;
    }
    return ans;
}
int fun2(int x) {
    return fun1(x,mod-2);
}
int main(){
    int t;
    cin>>t;
    while (t--){
    	int n,m;
	    cin>>n>>m;
	    cout<<(fun1(2,n-1)-1)*fun2(fun1(2,n-1))%mod*m%mod<<endl;
	}
	return 0;
}
	

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值