AtCoder Beginner Contest 368

A - Cut

思路

按照题意输出即可,I/O问题

AC代码

	#include<bits/stdc++.h>
	#define endl '\n'
	#define int int long long
	#define pb push_back
	#define bs bitset
	using namespace std;
	typedef pair<char,int> PCI;
	typedef pair<int,int> PII;
	typedef priority_queue<int> PQ;

	const int N = 2e5+10, MAX = 1e9, INF = -1e9;

	int n,k;
	int a[N];

	signed main()
	{
		ios::sync_with_stdio(false);
		cin.tie(0);
		cin>>n>>k;
		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

思路

按照题意模拟即可;

AC代码

	#include<bits/stdc++.h>
	#define endl '\n'
	#define int int long long
	#define pb push_back
	#define bs bitset
	using namespace std;
	typedef pair<char,int> PCI;
	typedef pair<int,int> PII;
	typedef priority_queue<int> PQ;

	const int N = 2e5+10, MAX = 1e9, INF = -1e9;

	int n;
	int a[N];
	int ans=0;
	int num=MAX;

	bool cmp(int a,int b){
		return a>b;
	}

	signed main()
	{
		ios::sync_with_stdio(false);
		cin.tie(0);
		cin>>n;
		for(int i=1;i<=n;i++)cin>>a[i];
		while(num>1){
			int key=0;
			ans++;
			for(int i=1;i<=n;i++){
				if(a[i]>0)key++;
			}
			num=key;
			sort(a+1,a+1+n,cmp);
			a[1]--;a[2]--;
		}
		cout<<ans-1<<endl;
		return 0;
	}

C - Triple Attack

思路

直接模拟一定会超时,不难发现每三次操作为一个周期,总伤害为5,所以我们打包处理即可,注意特殊处理下处理敌人之前和之后周期进行到哪里了,处理细节;

AC代码

	    #include<bits/stdc++.h>
    #define endl '\n'
    #define int int long long
    #define pb push_back
    #define bs bitset
    using namespace std;
    typedef pair<char,int> PCI;
    typedef pair<int,int> PII;
    typedef priority_queue<int> PQ;

    const int N = 2e5+10, MAX = 1e9, INF = -1e9;

    int t=1;
    int n;
    int a[N];
    int ans=0;

    signed main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>a[i];

            if(t==2){
                a[i]-=1;t=3;ans++;if(a[i]<1)continue;
            }
            if(t==3){
                a[i]-=3;t=1;ans++;if(a[i]<1)continue;
            }

            ans+=(a[i]/5)*3;
            a[i]%=5;

            if(a[i]==1){
                t=2;ans++;
            }
            else if(a[i]==2){
                t=3;ans+=2;
            }
            else if(a[i]>=3&&a[i]<5){
                t=1;ans+=3;
            }
            else continue;
        }
        cout<<ans<<endl;
        return 0;
    }

D - Minimum Steiner Tree

思路

选择一个目标节点作为最后生成树的根节点,进行DFS,问题的关键就在于判断过程中的某个节点是否需要保留,如果该节点及其子节点中存在目标节点则需要保留,否则舍弃,建立一个数组表示节点的去留,
\(dfs\)函数:

有两个参数,分别是当前点\(x\)和父节点\(fa\)
如果\(x\)是特殊点,那么一定要取。
枚举\(x\)的邻居\(y\),如果不是父亲(即是儿子),那么递归,考虑儿子要不要取:\(f_x=f_x V f_y\),答案就是数组之和;

AC代码

	#include<bits/stdc++.h>
	#define endl '\n'
	#define int int long long
	#define pb push_back
	#define bs bitset
	using namespace std;
	typedef pair<char,int> PCI;
	typedef pair<int,int> PII;
	typedef priority_queue<int> PQ;

	const int N = 2e5+10, MAX = 1e9, INF = -1e9;
	int n, k, cnt;
	int f[N]; 
	vector<int> g[N]; 

	void dfs(int x, int fa) 
	{
		for (int i = 0; i < g[x].size(); i++) 
		{
			int y = g[x][i];
			if (y == fa) continue; 
			dfs(y, x);
			f[x] |= f[y]; 
		}
	}

	signed main()
	{
		ios::sync_with_stdio(false);
		cin.tie(0);
		cin >> n >> k;
		for (int i = 1; i < n; i++)
		{
			int a, b;
			cin >> a >> b;
			g[a].push_back(b);
			g[b].push_back(a);
		}
		int root = 0;
		for (int i = 1; i <= k; i++)
		{
			int v;
			cin >> v;
			f[v] = 1; 
			if (!root) root = v; 
		}
		dfs(root, 0); 
		for (int i = 1; i <= n; i++)
			cnt += f[i]; 
		cout << cnt << endl;
		return 0;
	} 

t.b.c.

posted @ 2024-09-30 21:24  Oaths  阅读(9)  评论(0)    收藏  举报