ABC396 vp+部分题目题解(未完)

A:

问题陈述

给你一个长度为 \(N\) 的整数序列: \(A = (A_1,A_2,\ldots,A_N)\) .

请判断在 \(A\) 中是否有相同元素连续出现三次或三次以上的位置。

更正式地说,请判断是否存在一个整数 \(i\)\(1 \le i \le N-2\) 中的 \(A_i = A_{i+1} = A_{i+2}\) .

数据范围

  • \(3 \le N \le 100\)
  • \(1 \le A_i \le 100\)
  • 所有输入值均为整数。

模拟即可。

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,a[105],t[105],ans;
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	for(int i=1;i<=n-2;i++){
		if(a[i]==a[i+1]&&a[i+1]==a[i+2]){
			ans=1;
		}
	}
	if(ans==0){
		cout<<"No";
	}else{
		cout<<"Yes";
	}
    return 0;
}

B:

问题陈述

有一叠 \(100\) 纸牌,每张都标有整数 \(0\)

处理 \(Q\) 个查询。每个查询都属于以下情况之一:

  • 输入 \(1\) :将一张标有整数 \(x\) 的卡片放在堆栈顶部。
  • 类型 \(2\) :取出堆栈顶端的卡片,并输出写在该卡片上的整数。在此问题的限制条件下,牌堆中总是至少有一张牌。

数据范围

  • \(1 \le Q \le 100\)
  • \(1 \le x \le 100\)
  • 至少有一个查询类型为 \(2\)
  • 所有输入值均为整数。

栈加模拟。

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
int q;
stack<int> sta;
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	for(int i=1;i<=100;i++){
		sta.push(0);
	}
	cin>>q;
	while(q--){
		int op;
		cin>>op;
		if(op==1){
			int x;
			cin>>x;
			sta.push(x);
		}else{
			cout<<sta.top()<<"\n";
			sta.pop();
		}
	}
    return 0;
}

C:

问题陈述

\(N\) 个黑球和 \(M\) 个白球。
每个球都有一个值。第 \(i\) 个黑球( \(1 \le i \le N\) )的值是 \(B_i\) ,第 \(j\) 个白球( \(1 \le j \le M\) )的值是 \(W_j\)

选择 0 个或更多的球,使得所选黑球的数量至少等于所选白球的数量。在所有这样的选择中,求所选球的数值之和的最大值。

限制因素

  • \(1 \leq N,M \leq 2\times 10^5\)
  • \(-10^9 \leq B_i, W_j \leq 10^9\)
  • 所有输入值均为整数。

做法一:

根据题意,暴力。

做法二:

排序后贪心

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,m,a[200005],b[200005],sum[200005],ans;
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	for(int i=1;i<=m;i++){
		cin>>b[i];
	}
	sort(a+1,a+n+1,greater<int>());
	sort(b+1,b+m+1,greater<int>());
	for(int i=1;i<=m;i++){
		sum[i]=sum[i-1]+b[i];
	}
	for(int i=1;i<=m;i++){
		sum[i]=max(sum[i-1],sum[i]);
	}
	for(int i=1;i<=n;i++){
		a[i]+=a[i-1];
		ans=max(ans,sum[min(i,m)]+a[i]);
	}
	cout<<ans;
    return 0;
}

D:

问题陈述

给你一个简单相连的无向图,图中有 \(N\) 个顶点,编号为 \(1\)\(N\) ;有 \(M\) 条边,编号为 \(1\)\(M\) 。边 \(i\) 连接顶点 \(u_i\)\(v_i\) ,其标签为 \(w_i\)

在从顶点 \(1\) 到顶点 \(N\) 的所有简单路径(不经过同一顶点多次的路径)中,求路径上边的标签的最小 XOR。

关于 XOR 的说明 对于非负整数 \(A\)\(B\) ,它们的 XOR \(A \oplus B\) 定义如下:

  • \(A \oplus B\) 的二进制表示中,当且仅当 \(A\)\(B\) 的相同数位中恰好有一位是 \(1\) 时, \(2^k \,(k \ge 0)\) 对应数位上的数字是 \(1\) ;否则,它是 \(0\)

例如, \(3 \oplus 5 = 6\) (二进制为: \(011 \oplus 101 = 110\) )。
一般来说, \(k\) 整数 \(p_1, \dots, p_k\) 的 XOR 定义为 \((\cdots ((p_1 \oplus p_2) \oplus p_3) \oplus \cdots \oplus p_k)\) 。可以证明它与 \(p_1, \dots, p_k\) 的阶数无关。

数据范围

  • \(2 \leq N \leq 10\)
  • \(N-1 \leq M \leq \frac{N(N-1)}{2}\)
  • \(1 \leq u_i \lt v_i \leq N\)
  • \(0 \leq w_i \lt 2^{60}\)
  • 给定图是一个简单连接的无向图。
  • 所有输入值均为整数。

注意到 \(N \leq 10\) 所以爆搜即可。

点击查看代码
#include<bits/stdc++.h>
#define int unsigned long long
using namespace std;
int n,m,ans=LLONG_MAX;
struct edge{
	int v,w;
};
vector<edge> e[15];
bool vis[15];
void dfs(int u,int sum){
	if(u==n){
		ans=min(ans,sum);
		return;
	}
	if(vis[u]==1){
		return;
	}
	vis[u]=1;
	for(auto v:e[u]){
		dfs(v.v,sum^v.w);
	}
	vis[u]=0;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int u,v,w;
		cin>>u>>v>>w;
		e[u].push_back(edge{v,w});
		e[v].push_back(edge{u,w});
	}
	dfs(1,0);
	cout<<ans;
	return 0;
}
posted @ 2025-07-12 19:31  rzm120412  阅读(13)  评论(0)    收藏  举报