训练赛二

题目链接

B. 签到题,N-K+1;

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	printf("%d\n",n-m+1);
        return 0;
}

C.当pi=i-1时,取余的和最大,sum=1+2+····+(n-1)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
typedef long long ll;
int main()
{
	ll n;
	scanf("%lld",&n);
	if(n==1)
		printf("0\n");
	else
	{
		printf("%lld",n*(n-1)/2);
	}
        return 0;
}

E.题意为求构成树的种类,第i层的种类为a[i-1]^a[i],a[i]为的i层的数量

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
const int mod=998244353;
const int maxn1=1e5+10;
typedef long long ll;
ll a[maxn1];
ll abc(ll a,ll b)
{
	ll res=1;
	while(b)
	{
		if(b&1)
			res=(res*a+mod)%mod;
		a=(a*a+mod)%mod;
		b>>=1;
	}
	return res;
}
int main()
{
	ll n;
	ll x;
	ll ant=-1;
	bool flag=0;
	ll ans=1;
	scanf("%lld",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%lld",&x);
		if(i==0&&x!=0||i!=0&&x==0)
			flag=1;
		
		a[x]++;
		if(x>ant)
			ant=x;
	}
	if(flag==1)
		printf("0\n");
	else
	{
		for(int i=2;i<=ant;i++)
		{
			if(a[i]==0)
			{
				flag=1;
				break;
			}
			ans=(ans*abc(a[i-1],a[i])+mod)%mod;
//			printf("%lld\n",ans);
		}
		if(flag)
			printf("0\n");
		else
			printf("%lld\n",ans);
	}
	return 0;
}

F.题意可理解为求公共最大公约数。当公共最大公约数为1时 ,就不用再求了

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
typedef long long ll;
int gcd(int a,int b)
{
	int t;
	if(a<b)
	{
		t=a;
		a=b;
		b=t;
	}
	if(a%b==0)
		return b;
	else
		return gcd(b,a%b);
		
}
int main()
{
	int n,m;
	int ans;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%d",&m);
		if(!i)
			ans=m;
		if(ans==1)
			continue;
		ans=gcd(ans,m);
		
			
	}
	printf("%d\n",ans);
	return 0;
}

G.当我们每次用优惠券时的商品价格最大时,最划算,因为每次都是减少一半,可以用优先队列,M次循环,每次最大值出队,/2后再入队,最后求和。

优先队列

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
using namespace std;
typedef long long ll;
int main()
{
	int n,m;
	int x;
	ll ans=0;
	priority_queue<int> q;
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++)
	{
		scanf("%d",&x);
		q.push(x);
	}
	for(int i=0;i<m;i++)
	{
		x=q.top();
		q.pop();
		x/=2;
		q.push(x);
	}
	while(!q.empty())
	{
		ans+=q.top();
		q.pop();
	}
	printf("%lld\n",ans);
	return 0;
}

H.让开始每个人的分数为0,每赢一次加一分,最后加上初始分数减去总场数,判断是否大于一即可

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
typedef long long ll;
const int maxn=1e5+100;
int main()
{
	ll n,k,q;
	ll x;
	ll a[maxn];
	memset(a,0,sizeof(a));
	scanf("%lld%lld%lld",&n,&k,&q);
	for(int i=0;i<q;i++)
	{
		scanf("%d",&x);
		a[x]++;
	}
	for(int i=1;i<=n;i++)
	{
		if(a[i]+k-q>0)
			printf("Yes");
		else
			printf("No");
		if(i!=n)
			printf("\n");
//		printf("%d ",a[i]+k-q);
	}
	return 0;
}

I.模拟即可,遍历数组每次取最大值即可

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
typedef long long ll;
const int maxn=1e9+1;
int main()
{
	int n,a[100010];
	int ans=maxn;
	int ant=0;
	int ast=0;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
		scanf("%d",&a[i]);
	ans=a[0];
	for(int i=1;i<n;i++)
	{
		if(a[i]<=ans)
		{
			ans=a[i];
			ast++;
		}
		else
		{
			ans=a[i];
//			printf("ast :%d\n",ast);
			ant=max(ant,ast);
			ast=0;
		}
	}
	ant=max(ant,ast);
	printf("%d\n",ant);
	return 0;
}

J.

分析:首先计算出a[ i ],左右两边比a[ i ]小的个数,计算第一个a[ i ]为 k*r[ i ]+(k-1)*l [ i ],

第二个a[ i ]为  (k-1)*r[ i ]+(k-2)*l [ i ],累加可得(1+2+...+k)*r[ i ]+(1+2...+(k-1))*l [ i ]。

计算sam时,(k+1)*k/2前要加(long long)或者将k直接定义为long long 类型,否则溢出。

代码如下:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn=2e5+100;
const int mod=1e9+7;
int a[maxn];
int l[maxn];//记录左边比i要小的数 的个数 
int r[maxn];//记录右边比i要小的数 的个数
int main()
{
	int n,k;
	ll ans;
	ll sam;
	scanf("%d%d",&n,&k); 
	sam=(ll)(k+1)*k/2;//总和时要算右边比i小的次数 
	sam-=k; //总和时要算左边比i小的次数 
	sam=(sam+mod)%mod;
	for(int i=0;i<n;i++)
		scanf("%d",&a[i]);
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<i;j++)
			if(a[j]<a[i])
				l[i]++;
		for(int j=i+1;j<n;j++)
			if(a[j]<a[i])
				r[i]++;		 
	}
	ans=0; 
	for(int i=0;i<n;i++)
	{
		ans+=(l[i]*sam);
		ans%=mod;
		ans+=(r[i]*(sam+k));
		ans%=mod;
	}
	printf("%lld\n",ans);
	return 0;
}

M.ant存每个字符串已经形成的AB,ab用于存字符串第一个元素为B且最后一个元素为A,a用于存字符串最后一个元素为A,b用于存字符串第一个元素为B;

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<string.h>
using namespace std;
typedef long long ll;
int main()
{
	int n;
	int l;
	int ant=0,ab=0,a=0,b=0;
	int ans=0;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		char c[15];
		scanf("%s",c);
//		printf("%s\n",c);
		l=strlen(c);
		for(int j=0;j<l-1;j++)
		{
			if(c[j]=='A'&&c[j+1]=='B')
				ant++;
		}
		if(c[0]=='B'&&c[l-1]=='A')
			ab++;
		else if(c[0]=='B')
			b++;
		else if(c[l-1]=='A')
			a++;
	}
//	printf("ant:%d ab:%d a:%d b:%d\n",ant,ab,a,b);
	ans+=ant;
	if(ab!=0)
		ans+=(ab-1);
	if(a!=0&&ab!=0)
	{
		ans++;
		a--;
	}
	if(b!=0&&ab!=0)
	{
		ans++;
		b--;
	}
	ans+=min(a,b);
	printf("%d\n",ans);
	return 0;
}
/*
5
AB
AB
AB
AB
BB
6
*/
发布了40 篇原创文章 · 获赞 2 · 访问量 862

猜你喜欢

转载自blog.csdn.net/qq_43851311/article/details/103128047