集训2.1

Technocup 2020 - Elimination Round 1

https://codeforces.com/contest/1223

A - CME

题解

给出n个火柴判断是否可以组成等式,首先考虑构建等式的最小火柴数:4,所以当n小于4时答案为4-n。
当n为偶数时,显然成立:(1)+(n/2-1)=n/2.
当n为奇数时,补上一根火柴构成偶数即可

Code

#include<bits/stdc++.h>
#define IO  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std; 
 
const int inf=0x3f3f3f3f;
typedef long long ll; 
const int N= 1e5+7;
const ll mod=998244353;       

int main(){ 
    IO;
    int t=1;
    cin>>t;
    while(t--){  
        int n;
        cin>>n;
        if(n<=4)cout<<4-n<<endl;
        else cout<<(n&1)<<endl;
    }
    return 0;
}

B - Strings Equalization

题解

水题,因为可以随意变换所以只需要判断两个字符串是否有相同部分即可。

Code

#include<bits/stdc++.h>
#define IO  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std; 
 
const int inf=0x3f3f3f3f;
typedef long long ll; 
const int N= 1e5+7;
const ll mod=998244353;       

int main(){ 
    IO;
    int t=1;
    cin>>t;
    while(t--){  
        string x,y;
        cin>>x>>y;
        int a[30]={0};
        for (int i = 0; i < x.size(); ++i)
        {
            a[x[i]-'a']++;
        }int flag=0;
        for (int i = 0; i < y.size(); ++i)
        {
            if(a[y[i]-'a']){
                flag=1;break;
            }
        }if(flag)cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
}

C - Save the Nature

题解

用int计算最小公倍数,数据爆了
题意为给出一个序列你可以任意改变次序,并且次序为a的倍数的值乘以x%,是b的倍数的值乘以y%,加起来需要k,求需要序列中数的最小数量。
直接二分即可。
取数时越大越好,所以排序后从大数开始取。
中间判断时要注意两种情况都需要判断:a的倍数位置放比较大的数和a的倍数位置放比较小的数。只要一种情况满足即可。

Code

#include<bits/stdc++.h>
#define IO  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std; 
 
const int inf=0x3f3f3f3f;
typedef long long ll; 
const int N= 2e5+7;
const ll mod=998244353;       

ll gcd(int x,int y){
    if(!y)return (ll)x;else return (ll)gcd(y,x%y);
}
bool cmp(ll x,ll y){
    return x>y;
}
ll arr[N];
ll n,x,a,y,b;
ll k;
bool check(ll m){
    if(m==0){
        if(k>0)return false;
        else return true;
    }
    ll sum=0,cnt=0; 
        ll g=(ll)a*(ll)b/gcd(a,b);
        ll cnt1=m/a,cnt2=m/b,cnt3=m/g;
        for (int i = 1; i <= cnt3; ++i)
        {
            sum+=arr[i]*x/100+arr[i]*y/100;
        }cnt1-=cnt3,cnt2-=cnt3;
        int i = cnt3+1,p=cnt3+1;
        cnt=sum;
        for (int j = 1; j <= cnt2; ++j,++p)
        {
            cnt+=arr[p]*y/100;
        }
        for (int j = 1; j <= cnt1; ++j,++p)
        {
            cnt+=arr[p]*x/100;
        }
        for (int j=1; j <= cnt1; ++i,++j)
        {
            sum+=arr[i]*x/100;
        }
        for (int j=1; j <= cnt2; ++j,++i)
        {
            sum+=arr[i]*y/100;
        }
    if(sum>=k||cnt>=k)return true;
    else return false;
}

int main(){ 
    IO;
    int t=1;
    cin>>t;
    while(t--){   
        cin>>n;
        for (int i = 1; i <= n; ++i)
        {
            cin>>arr[i];
        }
        cin>>x>>a>>y>>b>>k; 
        sort(arr+1,arr+n+1,cmp);
        ll l=0,r=n,ans=-1,flag=0;
        while(l<=r){
            ll mid=(l+r)>>1;
            if(check(mid))
            {
                ans=mid;
                r=mid-1;
            }else l=mid+1;
        }cout<<ans<<endl;
    }
    return 0;
}

D - Sequence Sorting

题解

题意为你可以对一个序列进行任意次操作:选中一个数字并将此数字全部移到序列的前面或后面,询问将序列变为非减序列的最小操作次数。
操作数尽可能小就是不需要进行操作的数字尽可能多,
求出不需要进行操作的数,这些数彼此之间是有序的,即其中任何一个数出现的最后位置一定小于下一个数出现的开始位置,这样才能保证只需要操作其他数就一定可以完成排序工作。
对于一定要操作的数我们总可以保证一个数字操作一次就达到目的,所以只要找到最长的不需要进行操作的数即可。
在去重排完序的序列中找出连续的并且满足上述要求的最长序列,答案即是去重后的总长度减去最大的序列长度。

Code

#include<bits/stdc++.h>
#define IO  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std; 
 
const int inf=0x3f3f3f3f;
typedef long long ll; 
const int N= 3e5+7;
const ll mod=998244353;       

int a[N],b[N];

int main(){ 
    IO;
    int t=1;
    cin>>t;
    while(t--){  
        int n;
        cin>>n;
        map<int,int>mp;int ans=1,cnt=0;
        vector<int>v;
        for (int i = 1; i <= n; ++i)
        {
            int x;
            cin>>x;
            if(!mp[x]){
                a[x]=i;
                b[x]=i;cnt++;
                v.push_back(x);
            }else{
                a[x]=min(a[x],i);
                b[x]=max(b[x],i);
            }mp[x]=1;
        }sort(v.begin(),v.end());
        n=int(v.size());
        for (int i = 0; i < n; )
        {
            int j=i;
            while(j+1<n&&a[v[j+1]]>b[v[j]]){
                j++;
            }
            ans=max(ans,j-i+1);
            i=j+1;
        }cout<<n-ans<<endl;
    }
    return 0;
}
posted @   !^^!  阅读(72)  评论(0)    收藏  举报
编辑推荐:
· C#高性能开发之类型系统:从 C# 7.0 到 C# 14 的类型系统演进全景
· 从零实现富文本编辑器#3-基于Delta的线性数据结构模型
· 记一次 .NET某旅行社酒店管理系统 卡死分析
· 长文讲解 MCP 和案例实战
· Hangfire Redis 实现秒级定时任务,使用 CQRS 实现动态执行代码
阅读排行:
· C#高性能开发之类型系统:从 C# 7.0 到 C# 14 的类型系统演进全景
· 管理100个小程序-很难吗
· 基于Blazor实现的运输信息管理系统
· 如何统计不同电话号码的个数?—位图法
· 微信支付功能的设计实现与关键实践(UniApp+Java)全代码
点击右上角即可分享
微信分享提示