其他分享
首页 > 其他分享> > Codeforces Round #702 (Div.3)

Codeforces Round #702 (Div.3)

作者:互联网

A. Dense Array

链接: https://codeforces.com/contest/1490/problem/A
思路: 贪心。找到一队不满足的数,求最大值是最小值2的几次幂倍就好。
代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
 
int arr[55];
 
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,ans=0;
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
        {
            scanf("%d",arr+i);
            if(i>=2)
            {
                int cnt=0;
                int minn=min(arr[i],arr[i-1]);
                int maxn=max(arr[i],arr[i-1]);
                if(maxn>2*minn)
                {
                    do
                    {
                        minn*=2;
                        ++cnt;
                    }while(maxn>2*minn);
                    ans+=cnt;
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

B Balanced Remainders

链接: https://codeforces.com/contest/1490/problem/B
思路: 模拟转圈圈。求出c0、c1、c2。c1可以代价1转化为c2,c2可以代价1转化为c0,c0可以代价1转化为c1。先求出其品均值tar,即每个数的目标值。然后找出c0c1c2中大于tar的数,将多余的值向后不断转化,也就是不断转圈圈,直到三者相等。
代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
 
int c[3];
 
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int num=0,tar;
        c[0]=c[1]=c[2]=0;
        int x,n;
        scanf("%d",&n);
        while(n--)
        {
            scanf("%d",&x);
            if(x%3==0) ++c[0];
            if(x%3==1) ++c[1];
            if(x%3==2) ++c[2];
        }
            tar=(c[0]+c[1]+c[2])/3;
            while(c[0]!=c[1]||c[1]!=c[2]||c[0]!=c[2])
            {
                for(int i=0;i<=2;++i)
                {
                    if(c[i]>tar) {c[(i+1)%3]+=c[i]-tar;num+=c[i]-tar;c[i]=tar;}
                }
            }
            printf("%d\n",num);
    }
    return 0;
}

C - Sum of Cubes

链接 : https://codeforces.com/contest/1490/problem/C
思路 : 枚举+二分答案。a,b最大值为lim=\(x^{1/3}\),向下取整。然后在区间[1,lim]范围内对a枚举,再在区间[1,lim]内对b二分答案。
代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;

typedef long long ll;

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        ll x;
        scanf("%I64d",&x);
        ll lim=pow(x,1.0/3);
        ll lef,rig,mid;
        bool flag=0;
        for(ll i=1;i<=lim;++i)
        {
            rig=lim;lef=1;
            while(rig>=lef)
            {
                mid=(rig+lef)/2;
                ll tmp=mid*mid*mid+i*i*i;
                if(tmp>x) rig=mid-1;
                else if(tmp<x) lef=mid+1;
                else {flag=1;break;}
            }
            if(flag==1) break;
        }
        if(flag==1) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

D Permutation Transformation

链接: https://codeforces.com/contest/1490/problem/D
思路: 超简单的dfs,思路不用解释
代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;

typedef long long ll;

int arr[105],dep[105];

void dfs(int lef,int rig,int h=0)
{
    if(lef>rig) return;
    int maxn=0,index;
    for(int i=lef;i<=rig;++i)
    {
        if(arr[i]>maxn) {maxn=arr[i];index=i;}
    }
    dep[index]=h;
    dfs(lef,index-1,h+1);
    dfs(index+1,rig,h+1);
}

int main()
{
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;++i) cin>>arr[i];
        dfs(1,n);
        for(int i=1;i<=n;++i) cout<<dep[i]<<' ';
        cout<<'\n';
    }
    return 0;
}

E - Accidental Victory

链接: https://codeforces.com/contest/1490/problem/E
思路: 也不算难。sort一下,前缀和处理一下,然后在从后往前模拟一下。就出来了!
代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<algorithm>
#include<cstring>
using namespace std;

typedef long long ll;

ll arr[200010];
int st[200010],tmp[200010];

map<int,int> mp;

int main()
{
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--)
    {
        int n,x;
        cin>>n;
        mp.clear();
        memset(arr,0,sizeof(arr));
        int cnt=0,index=0;
        while(n--)
        {
            cin>>x;
            tmp[index++]=x;
            if(!mp[x]) st[cnt++]=x;
            ++mp[x];
        }
        sort(st,st+cnt);
        arr[0]=st[0]*mp[st[0]];
        for(int i=1;i<cnt;++i)
        {
            arr[i]+=arr[i-1]+st[i]*mp[st[i]];
        }

        int ans=mp[st[cnt-1]];
        mp[st[cnt-1]]=-1;
        for(int i=cnt-2;i>=0;--i)
        {
            if(arr[i]>=st[i+1]) {ans+=mp[st[i]];mp[st[i]]=-1;}
            else break;
        }
        cout<<ans<<'\n';
        for(int i=0;i<index;++i)
        {
            if(mp[tmp[i]]==-1) cout<<i+1<<' ';
        }
        cout<<'\n';
    }
    return 0;
}

F - Equalize the Array

链接: https://codeforces.com/contest/1490/problem/F
思路: 推公式。要离散化。公式为

\[n-m*c \]

n是所有元素的个数,c和题意一致,m是出现次数大于等于c的的元素个数(非重复)。所以先用桶装,然后离散化一下。然后for一遍求m*c的最大值就好。
代码:

#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
#include<algorithm>
using namespace std;

map<int,int> mp;
typedef long long ll;

int arr[200010];

int main()
{
    ios::sync_with_stdio(false);
    int n,t,x;
    cin>>t;
    while(t--)
    {
        cin>>n;
        mp.clear();
        int cnt=0;
        for(int i=1;i<=n;++i)
        {
            cin>>x;
            if(!mp[x]) arr[++cnt]=x;
            ++mp[x];
        }
        for(int i=1;i<=cnt;++i)
        {
            arr[i]=mp[arr[i]];
        }
        sort(arr+1,arr+cnt+1);
        int maxn=0;
        for(int i=1;i<=cnt;++i)
        {
            maxn=max(maxn,(cnt-i+1)*arr[i]);
        }
        cout<<n-maxn<<'\n';
    }
    return 0;
}

G. Old Floppy Drive

链接: https://codeforces.com/contest/1490/problem/G
思路: 施工中

标签:arr,int,ll,Codeforces,702,while,mp,Div.3,include
来源: https://www.cnblogs.com/Flowyuan-Foreverworld/p/14411145.html