A - Cut

先遍历后面一部分数,在遍历前面的。

#include <bits/stdc++.h>
#define int long long

using namespace std;

signed main()
{
	int n,k;
	cin>>n>>k;
	vector<int> a(n+1);
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	for(int i=n-k+1;i<=n;i++)
	{
		cout<<a[i]<<" ";
	}
	for(int i=1;i<=n-k;i++)
	{
		cout<<a[i]<<' ';
	}
	return 0;
}

B - Decrease 2 max elements

利用优先队列暴力模拟过程,数据较小,时间复杂度可以。

#include <bits/stdc++.h>
#define int long long

using namespace std;

signed main()
{
	int n;
	cin>>n;
	priority_queue<int> a;
	for(int i=0;i<n;i++)
	{
		int t;
		cin>>t;
		a.push(t);
	}
	int count=1;
	int ans=0;
	
	while(count==1)
	{
		
		int b,c;
		b=a.top();
		a.pop();
		c=a.top();
		a.pop();
		if(c<=0)
		{
			count==0;
			break;
		}
		ans++;
		a.push(b-1);
		a.push(c-1);
		
		
	}
	cout<<ans;
	return 0;
}

C - Triple Attack 每个攻击周期为1+1+3=5,对血量模5求攻击过几个周期和剩下多少血量。 对每个敌人攻击方式可能是 1 1 3 1 1 3,,, 1 3 1 1 3 1 1 3,, 3 1 1 3 1 1 3 1 ,,这三种。 这个由上一次的攻击次数决定。 对着三次分别进行分类讨论求出剩余血量的攻击次数。

#include <bits/stdc++.h>
#define int long long

using namespace std;

signed main()
{
	int n;
	cin>>n;
	vector<int> a(n+1,0);
	vector<int> b(n+1,0);
	int t=0;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		int k=t%3;
		if(k==0)
		{
			int c=a[i]/5;
			b[i]+=c*3;
			int d=a[i]%5;
			if(d==1)
			{
				b[i]++;
			}
			else if(d==2)
			{
				b[i]+=2;
			}
			else if(d>=3&&d<=4)
			{
				b[i]+=3;
			}
			t=(t+b[i])%3;
			
		}
		else if(k==1)
		{
			int c=a[i]/5;
			b[i]+=c*3;
			int d=a[i]%5;
			if(d==1)
			{
				b[i]++;
			}
			else if(d>=2&&d<=4)
			{
				b[i]+=2;
			}
			t=(t+b[i])%3;
		}
		else if(k==2)
		{
			int c=a[i]/5;
			b[i]+=c*3;
			int d=a[i]%5;
			if(d>=1&&d<=3)
			{
				b[i]++;
			}
			else if(d==4)
			{
				b[i]+=2;
			}
			t=(t+b[i])%3;
		}
		
		
		
	}
	int tt=0;
	for(int i=1;i<=n;i++)
	{
		tt+=b[i];
		//cout<<b[i]<<endl;
	}
	cout<<tt;
	
	return 0;
}

D - Minimum Steiner Tree

将一个需要备选的节点为根,若节点 u 一定要被包含,那么其父节点也一定要被包含。如果该点或者他以下的点需要备选,就加在该点上,然后 dfs 遍历每一个节点并回溯转移即可。

#include <bits/stdc++.h>

using namespace std;

const int kMaxN = 2e5 + 5;

int n, k, p, ans;
bool vis[kMaxN];
vector<int> g[kMaxN];

void dfs(int u, int fa) {
  for (int v : g[u]) {
    if (v != fa) {
      dfs(v, u), vis[u] |= vis[v];
    }
  }
}

int main() {
  ios::sync_with_stdio(0), cin.tie(0);
  cin >> n >> k;
  for (int i = 1, u, v; i < n; i++) {
    cin >> u >> v, g[u].push_back(v), g[v].push_back(u);
  }
  for (int i = 1, x; i <= k; i++) {
    cin >> x, vis[x] = 1, !p && (p = x);
  }
  dfs(p, 0);
  for (int i = 1; i <= n; i++) {
    ans += vis[i];
  }
  cout << ans;
  return 0;
}