"现代汽车前瞻杯"2025牛客暑期多校训练营3

F Flower

题意简化:

有一朵初始有n片花瓣的花,Yuki会按轮次摘花瓣:每轮操作中,她先摘a片花瓣,之后再摘b片花瓣;若剩余花瓣不足,就把剩下的全部摘完。这个过程会持续到所有花瓣被摘完为止。

Yuki的规则是:当且仅当最后一片被摘下的花瓣属于某一轮中“先摘的a片”时,她会离开;否则,她会留下。

你的任务是:先摘下一部分花瓣(但不能全摘完,至少要留1片),使得Yuki最终会留下。请计算你需要摘下的最少花瓣数;如果无论你怎么先摘(不摘完)都无法让她留下,则输出“Sayonara”。

输入数据:

  • 第一行输入一个整数t(1≤t≤100),表示测试用例的数量。
  • 每个测试用例包含三个整数n、a、b(1≤n,a,b≤10⁹),分别表示初始花瓣数、每轮先摘的花瓣数、每轮后摘的花瓣数。

思路

分类讨论

  1. n<=a 必然无法留下
  2. 如果n>a and n<=a+b ,为了让她留下可以不摘,
  3. n%(a+b)>a,说明摘完有限论之后,剩下的比a多,那么不摘也可以让她留下
  4. 除去上述的情况,那摘取n%(a+b)个,就可以让她最后摘完b个花瓣
点击查看代码
//"现代汽车前瞻杯"2025牛客暑期多校训练营3 
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

void solve() {
	ll n, a, b;
	cin >> n >> a >> b;
	if (n <= a) {
		cout << "Sayonara\n";
	} else if (n > a && n <= a + b || n % (a + b) > a) {
		cout << 0 << "\n";
	}else {
		cout << n % (a + b) << "\n";
	}
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int _ = 1;
	cin >> _;
	while (_--) {
		solve();
	}

	return 0;
}

D

Distant Control

你有n个机器人朋友,按顺序排成一排,标号从左到右为1, 2, ..., n。初始时,有些机器人是关闭的(状态为0),有些是开启的(状态为1)。

你的手机可以远程控机器人的电源状态,但有特定限制:存在一个常数a(1≤a≤n-1),你只能执行以下两种操作:

  1. 选择连续的a个全部处于开启状态的机器人,将它们全部关闭。
  2. 选择连续的a+1个全部处于关闭状态的机器人,将它们全部开启。

你的目标是:通过执行若干次操作(可以不执行任何操作),使最终处于开启状态的机器人数量尽可能多,求出这个最大可能值。

输入数据:

  • 第一行输入一个整数t(1≤t≤4×10⁴),表示测试用例的数量。
  • 每个测试用例包含两行:
    • 第一行是两个整数n和a(2≤n≤2×10⁵,1≤a≤n-1),分别表示机器人总数和操作相关的常数。
    • 第二行是一个长度为n的字符串s,由'0'和'1'组成,其中s[i]表示第i个机器人的初始状态('1'为开启,'0'为关闭)。

保证所有测试用例的n的总和不超过4×10⁵。

思路

可以思考到只要存在连续的a个开启的机器人,或者a+1个全部关闭的机器人,那么就可以通过不断操作使得全部开启
否则就是初始开的机器人数量

点击查看代码
//"现代汽车前瞻杯"2025牛客暑期多校训练营3
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

void solve() {
	ll n, a, cnt = 0;
	cin >> n >> a;
	string s;
	cin >> s;
	bool ok = false;
	for (ll i = 0; i < n; i++) {
		ll j;
		if (s[i] == '1') {
			for (j = i; j < i + a && j < n; j++) {
				if (s[j] != '1') {
					break;
				}
			}
			if (j - i == a) {
				ok = true;
			}
		} else {
			for (j = i; j < i + a + 1 && j < n; j++) {
				if (s[j] != '0') {
					break;
				}
			}
			if (j - i == a + 1) {
				ok = true;
			}
		}
		i = j - 1;
	}
	if (ok) {
		cout << n << "\n";
	} else {
		for (ll i = 0; i < n; i++) {
			if (s[i] == '1') {
				cnt++;
			}
		}
		cout << cnt << "\n";
	}
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int _ = 1;
	cin >> _;
	while (_--) {
		solve();
	}

	return 0;
}

J Jetton

题意简化:

Yuki和Ena进行回合制扑克游戏,初始时Yuki有x个筹码,Ena有y个筹码。每轮的胜负与支付规则如下:

  • 若两人筹码数不同,筹码少的一方获胜;
  • 若两人筹码数相同,Yuki获胜;
  • 输的一方需向胜者支付“胜者当前拥有的筹码数”等量的筹码。

当任意一方的筹码变为0时,游戏立即结束。请判断游戏是否会在有限轮数内结束;若会,还需计算从开始到结束的总轮数。

输入数据:

  • 第一行输入整数t(1≤t≤10⁵),表示测试用例数量。
  • 每个测试用例输入两个整数x和y(1≤x,y≤10⁹),分别为Yuki和Ena的初始筹码数。

思路

暴力测试,目测应该不会超过100轮

点击查看代码
#include<bits/stdc++.h>
 
using namespace std;
#define endl "\n"
const int maxn=110;
using ll=long long ;
const ll pr=1ll<<34;
 
 
int cnt;

void solve(){
    int x,y;
    cin>>x>>y;
    cnt=0;
    while(x && y){
        if(x<y){
            int t=x;
            x+=t;
            y-=t;
        }
        else if(x>y){
            int t=y;
            y+=t;
            x-=t;
        }
        else {
            int t=x;
            x+=t;
            y-=t;
        }
        ++cnt;
        if(cnt>100)
        {	
			cout<<-1<<'\n';
        	return;
        }
    }
    cout<<cnt<<endl;
}
int main()
{
    ios::sync_with_stdio(false);
   cin.tie(0);
    cout.tie(0);
    int T = 1;
    cin >> T;
    while(T--){
        solve();
    }return 0;
}

E Equal

题意简化:

Yuki 给你一个长度为 n 的正整数序列 a₁, a₂, ..., aₙ,你可以任意次数执行以下两种操作:

  1. 操作1:选择两个位置 ij(要求 1≤i<j≤n),再选一个正整数 d(要求 d 能同时整除 aᵢaⱼ,即 daᵢaⱼ 的公约数);然后将 aᵢ 更新为 aᵢ/daⱼ 更新为 aⱼ/d
  2. 操作2:选择两个位置 ij(要求 1≤i<j≤n),再选一个任意正整数 d;然后将 aᵢ 更新为 aᵢ×daⱼ 更新为 aⱼ×d

你的目标是判断:通过执行若干次上述操作后,能否让序列中所有元素都相等(即 a₁=a₂=...=aₙ)。

输入数据:

  • 第一行输入一个整数 t(1≤t≤10⁵),表示测试用例的数量。
  • 每个测试用例包含两行:
    1. 第一行是序列长度 n(1≤n≤10⁶);
    2. 第二行是 n 个正整数 a₁, a₂, ..., aₙ(1≤aᵢ≤5×10⁶),代表初始序列。
  • 保证所有测试用例的 n 之和不超过 2×10⁶(避免输入规模过大)。

思路

对于操作题的思考,可以考虑几种操作是否有神奇的组合达到化繁为简的效果

首先使得所有数相等,那么必然所有数的素因子个数相同
而通过两次操作,可以使得一个数*d,一个数不变,一个数/d,达到因数个数的转移,于是只有因数出现过偶数次或者n-因数次数是偶数就可以达到所有数相等
注意到n=2时直接判断两个数是否相同

点击查看代码
#include<bits/stdc++.h>

using namespace std;
#define endl "\n"
using ll=long long ;
const ll pr=1ll<<34;
int cnt=0;
int n,m;
const int maxn=1e6;
bool isprime[maxn*5];
int s[maxn];
int top=0;
void ola(){
	isprime[1]=1;
	for(int i=2;i<=maxn*5;++i){
		if(!isprime[i])
			s[++top]=i;
		for(int j=1;j<=top && i*s[j]<=maxn*5;++j){
			isprime[i*s[j]]=1;
			if(i%s[j]==0) break; 
		} 
	}
//	cout<<top<<endl;
}
void solve(){
	cin>>n;
	
	unordered_map<int,int>a; 
	int w[3];
	for(int i=1;i<=n;++i){
		int x;
		cin>>x;
		if(i<=2) w[i]=x;
		for(int j=1;j<=top && x>=s[j];++j){
			while(x%s[j]==0 && x!=1){
				x/=s[j];
				a[s[j]]++;
			}
			if(isprime[x]==0){
				a[x]++;
				break;
			}
		}
	}
	if(n==1){
		cout<<"YES"<<endl;
		return ; 
	}
	else if(n==2){
		if(w[1]!=w[2]) cout<<"NO"<<endl;
		else cout<<"YES"<<endl;
		return ;
	}
	for(auto [x,y]:a){
		//cout<<x<<" "<<y<<endl;
		y%=n;
		if((n-y)%2!=0 && y%2!=0){
			cout<<"NO"<<endl;
			return ;
		}
			
	}
	cout<<"YES"<<endl;
	return ;
	
}
int main(){
    //ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int T = 1;
    cin >> T;
    ola();
    while(T--){
        solve();
    }return 0;
}

A Ad-hoc Newbie

题意简化:

给定一个长度为 n 的正整数序列 f₁, f₂, ..., fₙ(满足每个 fᵢ 都在 1 ≤ fᵢ ≤ i 范围内),需要你构造一个 n阶方阵A(即行数和列数均为 n 的矩阵),同时满足以下3个条件:

  1. 元素范围:矩阵中每个元素 Aᵢⱼ(第 i 行第 j 列)都满足 0 ≤ Aᵢⱼ ≤ n
  2. 行mex条件:对每一行 i,这一行所有元素的 mex 值等于 fᵢ
  3. 列mex条件:对每一列 i,这一列所有元素的 mex 值也等于 fᵢ

其中,mex(最小未出现非负整数)的定义是:对于一个序列,mex最小的、没有在序列中出现过的非负整数(例如:序列 [0,1,3]mex2,序列 [1,2]mex0)。

题目保证:对任意合法的 f 序列,都存在满足条件的矩阵,你只需构造出任意一个即可。

输入数据:

  • 第一行输入整数 t1 ≤ t ≤ 2×10⁴),表示测试用例的数量;
  • 每个测试用例包含两行:
    1. 第一行是整数 n1 ≤ n ≤ 1414),表示序列长度和矩阵的阶数;
    2. 第二行是 n 个整数 f₁, f₂, ..., fₙ1 ≤ fᵢ ≤ i),表示给定的序列;
  • 保证所有测试用例的 之和不超过 2×10⁶(避免矩阵规模过大)。

思路

构造题

对角线元素a[i][i]初始为 1,确保每行 / 列包含数字 1。
对于i < j的位置,a[i][j]和a[j][i]均设为i+1,保证矩阵对称(行i和列i的元素完全相同),后续只需保证行mex正确,列mex自然也正确。

\(f_i = 1\)时:mex=1意味着 “0 必须出现,1 必须不出现”。原对角线a[i][i]是 1,修改为 0 后:
行i中包含 0(满足 “0 出现”);
行i中不再有 1(满足 “1 不出现”),因此mex为 1。

\(f_i > 1\)时:mex=x意味着 “0,1,...,x-1 必须全部出现,x 必须不出现”。修改a[i][x-1]和a[x-1][i]为 0 后:
行i中包含 0(通过a[i][x-1] = 0);
行i中包含 1(对角线a[i][i]仍为 1);
行i中包含 2 到 x-1(由初始化时的j+1保证,j从 1 到 x-2 时,j+1恰好覆盖 2 到 x-1);
行i中不包含 x(通过初始化逻辑和x ≤ i的约束,可证明 x 不会出现在行i中)。
因此mex为 x,满足要求。
给出一种构造代码

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int t,a[1500][1500],n,x;
int main(){
	cin>>t;
	while(t--){
		cin>>n;
		for(int i=1;i<=n;i++){
			a[i][i]=1;
			for(int j=i+1;j<=n;j++){
				a[i][j]=a[j][i]=i+1;
			}
		}
		for(int i=1;i<=n;i++){
			cin>>x;
			if(x==1){
				a[i][i]=0;
			}
			else {
				a[i][x-1]=a[x-1][i]=0;
			}
		}
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				cout<<a[i][j]<<" ";
			} 
			cout<<"\n";
		}
		
	} 
	
	return 0;
}

Bitwise Puzzle

题意简化

给定三个非负整数 $ a, b, c $,可进行最多 64 次以下操作(四选一执行):

  1. $ a $ 乘以 2;
  2. $ b $ 向下取整除以 2;
  3. $ a $ 与 $ b $ 按位异或(结果赋给 $ a $);
  4. $ b $ 与 $ a $ 按位异或(结果赋给 $ b $)。
    要求通过这些操作使 $ a = b = c $,若存在解则完成操作,否则报告无解(题目保证:若有解,步骤不超过 64 次)。

数据范围

  • 测试用例数 $ t : 1 \leq t \leq 10^4 $;
  • 每个用例的 $ a, b, c : 0 \leq a, b, c < 2^{31} $;
  • 操作次数上限:最多 64 次。

思路

1. 无解判定

当且仅当 $ a = b = 0 $ 且 $ c \neq 0 $ 时,无解(因操作无法从0生成非零值)。

2. 构造解的阶段化调整策略

若有解,通过分阶段调整 $ a $ 和 $ b $,最终使 $ a = b = c $,且操作次数不超过64次:

(1)对齐最高位

通过最多1次异或操作($ b \leftarrow b \oplus a $),让 $ a $ 和 $ b $ 的最高位相同,为后续调整提供“高位辅助”(确保 $ b $ 能参与 $ a $ 的高位翻转)。

(2)高位匹配 $ c $

让 $ a $ 不断乘2(左移,操作1),同时用异或操作($ a \leftarrow a \oplus b $,操作3)调整 $ a $ 的位:
由于 $ b $ 最高位为1,异或可翻转 $ a $ 的对应位,使 $ a $ 在“乘2推进高位”的过程中,逐步与 $ c $ 的高位匹配。

(3)低位匹配 $ c $

当 $ a $ 与 $ c $ 的最高位一致后,让 $ b $ 不断除以2(右移,操作2),同时继续用异或操作(操作3)调整 $ a $ 的低位,使 $ a $ 完全匹配 $ c $。

(4)同步 $ b $ 到 $ c $

将 $ b $ 除至0后,执行1次异或操作($ b \leftarrow b \oplus a $,操作4),此时 $ b = 0 \oplus a = a = c $,最终实现 $ a = b = c $。

核心思想

利用a,b的最高位,用异或分别将a的左右侧调整为与c一致,最后b=0,b^=a

点击查看代码

/*
           ▃▆█▇▄?
      ?◤?   ◥█▎
     ◢◤  ?     ?▉
  ?◤   ▂ ??  ▕█▎
 ◤ ?▅?◥▄ ?◣   █▊
? ▕▎◥?◣◤    ◢██
█◣ ◥▅█?      ?██◤
?█?▂        ◢██◤
◥██◣    ◢▄◤
   ?██▅▇?
 
为什么要看我的屎代码?怎么会有这么臭的代码啊(悲)
 
*/
#include<bits/stdc++.h>

using namespace std;
#pragma GCC optimize(2)
#pragma GCC optimize("O3")
using ll=long long;

#define endl "\n"
using pii=pair<ll,ll>;
const int maxn=2e5+10;
const int mod=1e9+7;
const ll inf=1e18;
int dx[] = {-1, 1, 0, 0, 0};
int dy[] = {0, 0, -1, 1, 0};


mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

inline ll read() {
	ll x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9') {
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0' && ch<='9')
		x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	return x*f;
}
void print(ll x) {
	if(x<0)
		putchar('-'),x=-x;
	if(x>9)
		print(x/10);
	putchar(x%10+'0');
	return;
}
ll qpow(ll a,ll b,ll p) {
	a%=p;
	ll res=1;
	while(b) {
		if(b&1) res=res*a%p;
		b>>=1;
		a=(a*a)%p;
	}
	return res%p;
}
ll inv(ll a,ll p) {
	return qpow(a,p-2,p)%p;
}
inline ll  lowbit(ll x) {
	return x&(-x);
}
inline ll gcd(ll a,ll b) {
	while(b) {
		ll c=b;
		b=a%b;
		a=c;
	}
	return a;
}	
 
ll lcm(ll a ,ll b) {
	return a*b/gcd(a,b);
}

#define lg __lg

void solve() {
	 ll a=read(),b=read(),c=read();
    if(a==0 && b==0 && c>0){
        puts("-1");
        return ;
    }
    if(a==b && b==c){
        puts("0");
        puts("");
        return ;
    }
    vector<int> ans;
    if(lg(b)<lg(a)){
        b^=a;
        ans.push_back(4);
    }
    
    for(int i=30;i>lg(b);--i){
        if(((a>>lg(b))&1)!=((c>>i)&1)){
            a^=b;
            ans.push_back(3);
        }
        a*=2;
        ans.push_back(1);
    }
    for(int i=lg(b);i>=0;--i){
        if(((c>>i)&1)!=((a>>i)&1)){
            a^=b;
            ans.push_back(3);
        }
        b/=2;
        ans.push_back(2);
    }
    ans.push_back(4);
    print((ll)ans.size());
    puts("");
    for(auto x:ans) {
        print(x);
        putchar(' ');
    }
    puts("");
    return ;
    
}

int main() {
	ll _=1;
	ios::sync_with_stdio(0);
	cin.tie(nullptr);
	_=read();
	while(_--) {
		solve();
	}
	return 0;
}

/*******************************************
 
............................................
............................................
............................................
............................................
.............................1ffLf1.........
............................GGGGGGGC........
....................8CCCftCCCCC1;LLG,.......
..................:CC8CCC.CCCCCCii..........
.................CC88CCCC.CCCCCCC...........
................CC88CCCCC .8.:8CCC..........
................888 CCCCC.88888G;;,.........
,................888CC88.888888888,.........
:::...............CCC888.888888888..........
:::::............Gi1tC8f888888C88,..........
:::::::,........111tttfffffLG8888...........
:::::::::,....ii111ttttttfffttG.............
::::::::::::i111tttffffffffffttt............
::::::::::11tttttfff....fffffftt ...........
..:::::::1Lf1tff,..........fffff1...........
....,:::iiftG::::::.........,LLGtL..........
::::::;:i11t:;;;;;;::,,,,,,,,, f1ii,::,,,,,,
::::::::i11t:::::::::::::::::::f111:::::::::
::::::::111:::::::::::::::::::::t111::::::::
:::::::i1if::::::,,,,,,,,,,,,,,:i111::::::,:
,,,,,::,8G,,,,,,,,,,,,,,,,,,,,,,,tL1:,,,,,,,
,,,,,,:LGL;,,,,,,,,,,,,,,,,,,,,,,,CLf,,,,,,,
,,,,,;LGGG,,,,:,,,,,,,,,,,,,,,,,,,LGCG,,,,,,
 
*******************************************/


 

posted @ 2025-09-19 22:42  归游  阅读(10)  评论(0)    收藏  举报