2024-08-27-ABC368

A - Cut

给定数组,将右边k个数挪到左边并输出。

image-20240826214758062

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,a[105],k;
int main()
{
	cin>>n>>k;
	for(int i=0;i<n;i++)
		cin>>a[i];
	for(int i=n-k,j=0;j<n;j++,i=(i+1)%n)
		cout<<a[i]<<" ";
	return 0;
}

B - Decrease 2 max elements

给定一个数组,每次将最大的两个数减一,直到只有一个或无正数。输出操作的次数。

image-20240826215400233

模拟即可

#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll n,a[105];
int main(){
	ll i,ans=0;
	cin>>n;
	for(i=0;i<n;i++)
	{
		cin>>a[i];
	}
	while(true)
	{
		sort(a,a+n);
		if(a[n-2]<=0)
		{
			break;
		}
		ans++;
		a[n-1]--,a[n-2]--;
	}
	cout<<ans<<'\n';
	return 0;
}

C - Triple Attack

有n个怪物,依次打他们,每个时刻会攻击一次,造成一点伤害,每攻击两次后的第三次攻击就可以打出三点伤害(即1,1,3,1,1,3这样循环),问打死所有怪物的时刻。

模拟,对于每个怪,我们先把打上个怪没打完的循环打掉,然后用剩下的血量对5取模,看还要打多少个循环,再处理一下剩下的血量即可。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll n,a[200005],t=0;
int main(){
	ll i;
	scanf("%lld",&n);
	for(i=0;i<n;i++)
	{
		scanf("%lld",&a[i]);
		while(t%3!=0&&a[i]>0)
		{
			t++;
			a[i]-=(t%3==0?3:1);
		}
		if(a[i]<=0)
		{
			continue;
		}
		t+=(a[i]/5)*3;
		a[i]%=5;
		while(a[i]>0)
		{
			t++;
			a[i]-=(t%3==0?3:1);
		}
	}
	printf("%lld\n",t);
	return 0;
}

D - Minimum Steiner Tree

给定一棵树,问保留k个指定顶点后,联通的最小顶点数是多少。

以某一个保留的点为根进行的dfs,对于每一个点,如果子树里有保留的点,那么当前点也一定需要保留,算一遍就好了。

#include <bits/stdc++.h>
#define ll long long
#define N 200010
using namespace std;
ll n,k,sz[N];
vector<ll> vt[N];
void dfs(ll x,ll lst)
{
	ll i;
	for(i=0;i<vt[x].size();i++)
	{
		if(vt[x][i]!=lst)
		{
			dfs(vt[x][i],x);
			sz[x]+=sz[vt[x][i]];
		}
	}
	return;
}
int main(){
	ll i,x,y;
	scanf("%lld%lld",&n,&k);
	for(i=1;i<n;i++)
	{
		scanf("%lld%lld",&x,&y);
		x--,y--;
		vt[x].push_back(y);
		vt[y].push_back(x);
	}
	while(k--)
	{
		scanf("%lld",&x);
		x--;
		sz[x]=1;
	}
	dfs(x,-1);
	ll ans=0;
	for(i=0;i<n;i++)
	{
		ans+=(sz[i]>0);
	}
	printf("%lld\n",ans);
	return 0;
}

E - Train Delay

这道题比G题通过的人数还少。

给定n条火车线路,每一条火车线路给定起点、终点、发车时间、到达时间。

现在已知第一条火车线路会延误x1分钟,请问剩下来所有线路的延误时间,使本来能在一个地方换乘的火车,之后也能换乘(即两辆火车一个到达早于另一辆发车,在延误后依然是到达早于发车)

image-20240827004025585

首先这题肯定是个贪心,我们对于每一列火车都让其能尽量早发车就行。

我们按照时间顺序去处理每一辆火车的出发和到达,因为题目限制,延误后的没一辆火车的出发到达顺序应该都是不变的,并且维护一个数组,用于记录每个站点的火车的最晚到站时间tm[]。

遇到一个火车的出发时(设是从x出发),我们可以根据这个数组计算出这个火车出发所需要的延误时间,即tm[x]-s,就是刚好这个站之前的火车到达后出发。

遇到一个火车的到达时,就去更新一下我们的tm数组即可。

这题不难,不知道为什么人少。

#include <bits/stdc++.h>
using namespace std;
int main() 
{
	int N, M, X0;
	cin >> N >> M >> X0;
	
	vector<int> A(M), B(M), S(M), T(M);
	for (int i = 0; i < M; i++) {
		cin >> A[i] >> B[i] >> S[i] >> T[i];
		A[i]--;
		B[i]--; 
	}
	
	vector<array<int, 3> > e(2 * M);
	for (int i = 0; i < M; i++) {
		e[2 * i] = {S[i], 1, i};
		e[2 * i + 1] = {T[i], 0, i};
	}
	
	sort(e.begin(), e.end());
	
	vector<int> X(M);
	vector<int> tm(N);
	X[0] = X0;
	for (auto [t, o, i] : e) {
		if (o == 1) {
			X[i] = max(X[i], tm[A[i]] - S[i]);
		} else {
			tm[B[i]] = max(tm[B[i]], T[i] + X[i]);
		}
	}
	
	for (int i = 1; i < M; i++) {
		cout << X[i] << " \n"[i == M - 1];
	}
	
	return 0;
}

F - Dividing Game

给定n个数,两个人玩游戏,每一轮选一个数,将其变成这个数的真因子,无法操作就输了,问谁赢。

经典取石子,对于每一个数,把这个数操作到1的操作次数为这个数的质因子数量(可以理解为把这个数质因数分解,然后每次可以拿走任意数量的质因子),那么就是有n堆石子,谁取完就赢,和取石子游戏一模一样了,结果就是每一堆的石子数量相互异或,最后异或和为0先手必败,否则先手必胜。

#include <bits/stdc++.h>
using namespace std;
int n,ans;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cin>>n;
	for(int i=0;i<n;i++){
		int x,sg=0;
		cin>>x;
		for(int j=2;j<=sqrt(x);j++)
		{
			while(x%j==0){
				x/=j;
				sg++;
			}
		}
		if(x!=1) sg++;
		ans^=sg;
	}
	if(ans) cout<<"Anna";
	else cout<<"Bruno";
	return 0;
}
posted @ 2024-11-30 23:27  ~清渠~  阅读(0)  评论(0编辑  收藏  举报