牛客周赛 Round 70(A~F)

比赛链接:
是的,这次我还是没有AK,F题写了快一小时20多分钟,E题快写了20多分钟,没时间做G了

A.小苯晨跑

题面:
现在正在晨跑的小苯面前有四个数据,他想知道这些数据是否乱飞了,请你帮他确定吧。
(如果所有数据都相等,则认为数据没有乱飞,反之则乱飞了。)
输入:
本题含有多组测试数据。

  • 第一行一个正整数 T (1T1000) ,表示测试数据的组数。

  • 接下来对于每组测试数据,输入包含一行四个正整数 a1,a2,a3,a4 (1a1,a2,a3,a41000) ,表示小苯面前的四个数据。
    输出:
    对于每组测试数据,输出一行一个字符串。
    如果当前的数据乱飞了,则输出"YES",否则输出一个 "NO"。
    (都不包含双引号。)
    样例:
    2
    2 2 2 2
    1 2 3 3


NO
YES
思路:签到,直接和第一个数比较就好了

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll                                   long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
ll ksm(ll x, ll y)
{
	ll ans = 1;
	while (y)
	{
		if (y & 1)
		{
			ans = ans % mod * (x % mod) % mod;
		}
		x = x % mod * (x % mod) % mod;
		y >>= 1;
	}
	return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
	if (y == 0)
		return x;
	else
		return gcd(y, x % y);
}
void fio()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}
ll a[5];
int main()
{
	fio();
	ll t;
	cin>>t;
	while(t--)
	{
		ll ans=0;
		for(ll i=1;i<=4;i++)
		{cin>>a[i];
		if(a[i]==a[1])ans++;
		}
		if(ans==4)
		cout<<"NO"<<endl;
		else cout<<"YES"<<endl;
	}
	return 0;
}

B.小苯过马路

题面:
小苯生活在遥远的 B 星球,这天他正在等红绿灯,已知 B 星球的交规是:红灯有 𝑥秒,绿灯有 𝑦 秒,红灯和绿灯是交替亮灯的。(红灯上的时间从 𝑥减少到 1后,再过一秒灯就会变成绿色,同时灯显示的时间也会变成 𝑦;绿灯也同理。)
已知目前红绿灯颜色为 𝑐,灯显示的时间为 𝑘,小苯过马路需要花费的时间为 t
遵守交规的小苯想知道,从此刻开始到他走到马路对面,最少经过多少秒,请你帮他算一算吧。(小苯一旦开始过马路就不会停下脚步。)
输入:
输入包含一行,四个数字 x,y,k,t (1x,y,k,t1000,ty) 和一个字符 c

分别表示该路口红灯和绿灯的时间 x,y,和目前灯上显示的数字 k,以及小苯通过马路需要花费的时间 t 以及目前灯的颜色 c ('G' 表示绿灯,'R' 表示红灯)。

(保证输入的时间是合法的,即如果 c=G,则 ky,否则 kx。)
输出:
输出一行一个整数,表示小苯走到马路对面最少经过的秒数。
样例:
1:
30 30 10 10 G
————————————
10
2:
30 40 5 10 G
————————————
45
思路:简单思维,绿灯能走就走,不行就等到下次绿灯开始就走,红灯得等到绿灯才能走。

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll                                   long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
ll ksm(ll x, ll y)
{
	ll ans = 1;
	while (y)
	{
		if (y & 1)
		{
			ans = ans % mod * (x % mod) % mod;
		}
		x = x % mod * (x % mod) % mod;
		y >>= 1;
	}
	return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
	if (y == 0)
		return x;
	else
		return gcd(y, x % y);
}
void fio()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}
ll a[5];
int main()
{
	fio();
	ll x,y,k,t;
	char f;
	cin>>x>>y>>k>>t>>f;
	ll ans=0;
	if(f=='G')
	{
		if(t<=k)
		ans=t;
		else 
		ans=k+x+t;
	}
	else 
	{
		ans+=k+t;
	}
	cout<<ans<<endl;
	return 0;
}

C.小苯的字符串染色

题面:
小苯有一个长度为 n 的字符串 s ,其中有一些字符是黑色的,其余则为白色,他希望你可以给s 涂色,使得涂完后的 s 是纯白色的。

具体的涂色操作:

  • 选择一个长度为奇数的区间 [l,r] (1lrn) 同时 rl+1 是奇数,接着将区间内的字符按照:白黑白黑白…的方式涂色,即白色开头、白色结尾、同时黑白交替的样式。

小苯限制你最多进行 n 次涂色操作,请你构造一个合法涂色方案,使得涂色完后的字符串是全白色的吧,注意你不必最小化操作次数。

(注意,已经涂好颜色的地方依然可以被后续的涂色覆盖。)
输入:
本题含有多组测试数据。

第一行一个正整数 T(1T100),表示测试数据的组数。

接下来对于每组测试数据,输出包含两行:

第一行一个正整数 n(1n5000),表示字符串 s 的长度。

第二行一个长度为 n的 01 串 s。(保证 s 仅有字符 '0' 和 '1' 构成,其中 '0' 代表白色,'1' 代表黑色。)

(保证所有测试数据中, n 的总和不超过 5000。)
输出:
对于每组测试数据,第一行输出一个整数 m(0mn),表示进行操作的次数。

接下来 m 行,每行两个正整数 l,r(1lrn),((rl+1),表示对 sl,sl+1,,sr 这一段区间执行涂色操作。

(有多解输出任意即可,可以证明一定有解。)
样例:
1
6
101101
————————
2
1 3
4 6
思路:思维+遍历,简单题,对每一个单位进行操作就好了

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll                                   long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
ll ksm(ll x, ll y)
{
	ll ans = 1;
	while (y)
	{
		if (y & 1)
		{
			ans = ans % mod * (x % mod) % mod;
		}
		x = x % mod * (x % mod) % mod;
		y >>= 1;
	}
	return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
	if (y == 0)
		return x;
	else
		return gcd(y, x % y);
}
void fio()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}
ll a[5];
int main()
{
	fio();
	ll t;
	cin>>t;
	while(t--)
	{
		ll n;
		cin>>n;
		string f;
		cin>>f;
		cout<<f.size()<<endl;
		for(ll i=0;i<f.size();i++)	
		{
			cout<<i+1<<" "<<i+1<<endl;
		}
	}
	return 0;
}

D.小苯的能量项链

小苯有一个含有 𝑛颗珠子的“能量项链”,珠子排成一排,其中第 𝑖颗珠子的能量为 𝑎𝑖

但是这个项链并不稳定,如果项链的珠子个数不少于 3 个,则它即将发生“崩坏”,即:除了第一颗珠子和最后一颗珠子以外的其余所有珠子都将销毁,最终只留下第一颗和最后一颗珠子。

小苯现在希望项链在“崩坏”后保留尽可能多的能量,为此他可以在崩坏前执行以下的操作:

∙ 去掉项链的第一颗珠子(也就意味着项链原本的第二颗珠子将会变成第一颗)。

∙ 去掉项链的最后一颗珠子(也就意味着项链原本的倒数第二颗珠子将会变成最后一颗)。

两种操作各自均需要花费 1秒时间,而现在距离项链发生“崩坏”仅剩 k 秒,小苯想知道,他最多可以保留住多少能量,请你帮他算一算吧
输入:
输出:
对于每组测试数据,输出一行一个整数表示小苯能保留的最大能量。
样例:
2
5 2
2 3 4 5 2
1 1
114514
————————
8
114514
思路:特判n=1。先判断n-k<=2,如果成立则答案为数组中的最大和次大值之和。否则用前缀和后缀数组去维护最大值,然后去询问前k+1个位置就好了,然后用后缀数组求出另一个最大值,再这k+1个最大值加和中取个最大值就好了

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll                                   long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
ll ksm(ll x, ll y)
{
	ll ans = 1;
	while (y)
	{
		if (y & 1)
		{
			ans = ans % mod * (x % mod) % mod;
		}
		x = x % mod * (x % mod) % mod;
		y >>= 1;
	}
	return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
	if (y == 0)
		return x;
	else
		return gcd(y, x % y);
}
void fio()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}
ll a[650000];
ll pre[650000];
ll sub[650000];
int main()
{
	fio();
	ll t;
	cin>>t;
	while(t--)
	{
		ll n,k;
		cin>>n>>k;
		for(ll i=1;i<=n;i++)cin>>a[i];
		if(n==1)
		{
			cout<<a[1]<<endl;
			continue;
		}
		if(n-k<=2)
		{
			sort(a+1,a+1+n);
			cout<<a[n]+a[n-1]<<endl;
		}
		else 
		{
			for(ll i=1;i<=n;i++)
			{
				pre[i]=max(pre[i-1],a[i]);
			}
			sub[n+1]=0;
			for(ll i=n;i>=1;i--)
			{
				sub[i]=max(sub[i+1],a[i]);
			}
			ll ans=a[1]+a[n];
			for(ll i=1;i<=k+1;i++)
			{
				ans=max(ans,pre[i]+sub[n-(k-i+1)]);
			}
			cout<<ans<<endl;
		}
	}
	return 0;
}

E.小苯的最短路

题面:
小苯有一个 n 个点的无向完全图,编号从 1 到 n,其中 i 号点和 j 号点之间的边权为 ij

他想知道从 1 号点出发到达所有点的最短路,请你帮他算一算吧。(其中 表示按位异或运算。但为了避免输出数据量过大,你只需要输出到达所有点的最短路的异或和即可。)
输入:
本题含有多组测试数据。

第一行一个正整数 T(1T105),表示测试数据的组数。

接下来 T 行,每行一个正整数 n(1n109) 表示完全图的点数。
输出:
对于每组测试数据,输出包含一行一个正整数 S,表示到所有点的最短路的异或和,即:令 di 表示从 1 到 i 号点的最短路,则 S=d1d2d3dn
样例:
3
1
2
4
————————
0
3
4
思路:画了会,发现了所有的每个di的值,都是1i,所以直接套用规律公式,然后看1的数量奇偶性考虑异或1就行了。规律公式直接看代码吧

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll                                   long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
ll ksm(ll x, ll y)
{
	ll ans = 1;
	while (y)
	{
		if (y & 1)
		{
			ans = ans % mod * (x % mod) % mod;
		}
		x = x % mod * (x % mod) % mod;
		y >>= 1;
	}
	return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
	if (y == 0)
		return x;
	else
		return gcd(y, x % y);
}
void fio()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}
ll q(ll x)
{
	if(x%4==0)
	return x;
	else if(x%4==1)
	return 1;
	else if(x%4==2)
	return x+1;
	else 
	return 0;
}
int main()
{
	fio();
	ll t;
	cin>>t;
	while(t--)
	{
	ll n;
	cin>>n;
	if(n==1)
	{
		cout<<0<<endl;
	}
	else if(n==2)
	cout<<3<<endl;
	else 
	{
		//cout<<q(n)<<endl;
		cout<<(q(n)^(n%2==0?0:1))<<endl;
	}
	}
	return 0;
	// 1 2 3 4 5 6 7 8 9 10
	// 0 3 0 4 0 0 0 8 0 0
}

F.小苯的优雅好序列

题面:、
小苯认为满足以下任一条件的序列 a 是优雅的。

  • |a|=1
  • 对于所有 i(1i|a|) ,都存在 j(1j|a|,ji) ,使得aj%ai=0ai%aj=0

小苯认为一个长度为 n 的数组 a 是好数组,当且仅当a 所有的连续子数组都优雅。即对于所有 l,r(1lrn)al,al+1,,ar 都是一个优雅的序列。

现在小苯有一个数组 a 和正整数 k ,他想知道有多少个不超过k 的正整数 x(1xk) ,都有:a1+x,a2+x,,an+x 是一个好数组,请你帮他算一算吧。
输入:
每个测试文件内都包含多组测试数据。

第一行一个正整数 T (1T500) ,表示测试数据的组数。

接下来对于每组测试数据,输入包含两行。

  • 第一行两个正整数 n,k (1n5×104,1k109) ,表示数组 a 的长度。
  • 第二行 n 个整数 ai (1ai109) ,表示数组 a

(保证所有测试数据中 n 的总和不超过 6×104 。)
输出:
输出 T 行,每行两个整数 cnt,sum,分别表示不同的 x数字个数,以及这些 x 的和。
样例:
3
5 10
7 79 1 7 1
2 1000000000
1 2
1 100
1000000000
——————————
3 8
0 0
100 5050
思路:题目描述有问题?其实这个|是整除的意思,这里改了题面,牛客没改。对于所有数都相等时进行特判。不相等时,思考如何优化?
首先对于两个相邻且相等的数,任意x都是可以的,所以寻找相邻不相等的数,并把小值和大值用set<pair<ll,ll>>进行存储,遍历完后
对于这个set<pair<ll,ll>>进行遍历小值设为l,大值设为r,可以得出 x+rx+l=z(整数),显然可得出x满足 rlx+l=z(整数)即为符合答案(这个就直接对r-l进行因数分解就好了),然后首先求出一次所有的可能答案并用set<ll>存储起来,后面就用set<pair<ll,ll>>里的数对去检验已储存的答案,不对的先用vector存起来,这次遍历完后,立马遍历vector删除不符合的数,由于每个数对都不一样,存储的答案减少的会很多,所以总体时间复杂度很小,这个也算是经典容斥方法了,类似于筛子吧。

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
//#include<bits/stdc++.h>
#include <unordered_map>
#define ll                                   long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
ll ksm(ll x, ll y)
{
	ll ans = 1;
	while (y)
	{
		if (y & 1)
		{
			ans = ans % mod * (x % mod) % mod;
		}
		x = x % mod * (x % mod) % mod;
		y >>= 1;
	}
	return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
	if (y == 0)
		return x;
	else
		return gcd(y, x % y);
}
void fio()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}
ll a[650000];
ll b[650000];
set<pair<ll,ll>>p;
set<ll>q;
vector<ll>op;
int main()
{
	fio();
	ll t;
	cin>>t;
	while(t--)
	{
		op.clear();
		q.clear();
		p.clear();
		   ll n,f;
	       cin>>n>>f;
		   ll gs=0;
		   for(ll i=1;i<=n;i++)
		   {
			cin>>a[i];
			if(a[i]==a[1])
			gs++;
	       }
			if(gs==n)
			{
				cout<<f<<" "<<(1+f)*f/2<<endl;
				continue;
			}
			set<ll>q;
			ll ko=0;
			ll zk,zr;
			for(ll i=1;i<n;i++)
			{
				ll l=a[i],r=a[i+1];
				if(l>r)
				swap(l,r);
				if(l==r)continue;
				p.insert({l,r});
			}
			for(auto j:p)
			{
				ll l=j.first,r=j.second;
				//cout<<l<<" "<<r<<endl;
				op.clear();
				if(ko==0)
				{
					r-=l;
					for(ll u=1;u*u<=r;u++)
					{
						if(r%u==0)
						{
							if(u-l>=1&&u-l<=f)
							{
								q.insert(u-l);
							}
							if(r/u-l>=1&&r/u-l<=f) 
							{
								q.insert(r/u-l);
							}
						}
					}
					ko=1;
					//cout<<q.size()<<endl;
				}
				else 
				{
					//cout<<r<<" "<<l<<endl;
					for(auto k:q)
					{
						//cout<<k<<endl;
						if((r+k)%(l+k)==0)
						{
							continue;
						}
						else 
						{
							op.push_back(k);
						}
					}
					for(auto k:op)
					q.erase(k);
					if(q.size()==0)
					break;
				}
			}
			ll ans=0;
			for(auto j:q)
			{
				ans+=j;
			}
			cout<<q.size()<<" "<<ans<<endl;
	}
}

posted @   长皆  阅读(96)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示