2022.4.8

Codeforces Round #781 (Div. 2)

A. GCD vs LCM

啊,太久没接触最小公倍数了脑子抽了相成了最大公倍数,导致搞了很久。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
int main()
{
    cin.tie(nullptr)->sync_with_stdio(false);
    int t;
    cin >> t;
    while(t--)
    {
        ll n;
        cin >> n;
        if(n%4==0)
        {
            ll x = n / 4;
            cout << x << ' ' << x << ' ' << x << ' ' << x << '\n';
        }
        else 
        {
                n -= 2;
                ll x = n / 2;
                if(n&1)
                {
                    cout << x << ' ' << x + 1<<' ' ;
                }
                else
                    cout << x-1 << ' ' << x+1 << ' ';
                cout << "1 1" << '\n';
        }
    }

    return 0;
}

B. Array Cloning Technique

呃呃,如果要把一个数组变成全部一样且操作次数最少的话,肯定得挑相同元素最多的那个,每次复制我们可以使原来元素的个数翻倍,然后再swap过去,花费1+x次,不断重复这个过程直到全部交换完

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
int a[N];
int main()
{
    cin.tie(nullptr)->sync_with_stdio(false);
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        map<int, int> mp;
        cin >> n;
        for (int i = 1; i <= n;i++)
        {
            cin >> a[i];
            mp[a[i]]++;
        }
        int cnt = 0;
        for (int i = 1; i <= n;i++)
        {
            cnt = max(cnt, mp[a[i]]);
        }
        int res = n - cnt;
        if(res==0)
        {
            cout << 0 << '\n';
        }
        else
        {
            int ans = 0;
            while(cnt<n)
            {
                if(cnt+cnt>n)
                {
                    ans += 1 + n - cnt;
                    break;
                }
                ans += (1 + cnt);
                cnt += cnt;
            }
            cout << ans << '\n';
        }
    }
      
    return 0;
}

C. Tree Infection

贪心题,但是写着写着胡思乱想了,看了题解可以用二分来贪心,首先肯定得先感染儿子最多的,感染其中一个儿子剩下的每次都可以感染一个,二分感染的时间,同时对于每个儿子集合,从大到小排序然后求出能感染儿子的,对于第i个被感染的,剩下的能在mid时间内感染mid-i个,然后还需要加上而外感染的和一开始感染的第一个点。即mid>=cnt+ans

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=2e5+10,INF=1e9;
vector<int> p[N];
int q[N],cnt;
bool check(int mid)
{
    int ans = 0;
    for (int i = 1; i <= cnt;i++)
    {
        if(q[i]-(mid-i)>0)
        {
            ans += q[i]-(mid-i);
        }
    }
    return mid >= ans + cnt;
}
bool cmp(int a,int b)
{
    return a > b;
}
int main()
{
    cin.tie(nullptr)->sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin >> n;
        for (int i = 1; i <= n;i++)
        {
            p[i].clear();
            q[i] = 0;
        }
        for (int i = 2; i <= n;i++)
        {
            int x;
            cin >> x;
            p[x].push_back(i);
        }
        cnt = 1;
        for (int i = 1; i <= n;i++)
        {
            if(p[i].size())
                q[++cnt] = p[i].size() - 1;
        }
        sort(q + 1, q + 1 + cnt, cmp);
        int l = 1, r = n;
        while(l<r)
        {
            int mid = l + r >> 1;
            if(check(mid))
            {
                r = mid;
            }
            else
                l = mid + 1;
        }
        cout << l << '\n';
    }

    return 0;
}

Codeforces Round #640 (Div. 4)


posted @ 2022-04-09 19:24  menitrust  阅读(6)  评论(0编辑  收藏  举报