Codeforces Round #697 (Div. 3)-cf补题

Codeforces Round #697 (Div. 3)

https://codeforces.com/contest/1475

D. Cleaning the Phone

个人感觉D题比较难一点,也可能是当时没有想清楚!!
题意就是如何取尽可能多的ai并且bi尽可能小,(当时没有注意到bi的取值: 1=<bi<=2),因为b只有两种取值:1和2,那么就只有三种最优方案,即:只取bi为1的、只取bi为2的、两个都取。
接下来就是将bi为1和2的两种ai分类排序,将bi为2的ai序列求前缀和。然后遍历bi为1的ai,在每一次取完后判断此时取bi为2是否为最佳,直到取bi为1的ai总和大于等于m为止,最后再和只取bi为2的情况比较一下即可。

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=1e9+7;   

bool cmp(ll x,ll y){
    return x>y;
}

ll a[N],b[N],f[N];

int main(){ 
    IO;
    int t=1;
    cin>>t;
    while(t--){
        int n; 
        ll m;
        cin>>n>>m;
        ll sum=0;
        int ans=1e9;
        vector<ll>x[3];
        for (int i = 1; i <= n; ++i)
        {
            cin>>a[i];
        }
        for (int i = 1; i <= n; ++i)
        {
            cin>>b[i];
            x[b[i]].push_back(a[i]);
        }
        sort(x[1].begin(),x[1].end(),cmp);
        sort(x[2].begin(),x[2].end(),cmp);
        int len1=int(x[1].size()),len2=int(x[2].size());
        for (int i = 0; i < len2; ++i)
        {
            if(!i)f[i]=x[2][i];
            else f[i]=f[i-1]+x[2][i];
        }
        for (int i = 0; i < len1; ++i)
        {
            sum+=x[1][i];
            if(sum>=m){
                ans=min((i+1),ans);
                break;
            }
            ll k=m-sum;
            int pos=lower_bound(f,f+len2,k)-f;
            if(pos==len2)continue;
            ans=min(ans,(i+1+(pos+1)*2));
        }
        int pos=lower_bound(f,f+len2,m)-f;
        if(pos<len2){
            ans=min(ans,(pos+1)*2);
        }
        if(ans==1e9)cout<<-1<<endl;
        else cout<<ans<<endl;
    }
    return 0;
}

F. Unusual Matrix

个人感觉这一题不该放到F题,昨晚见到F题的时候只剩十分钟了!
题意要求矩阵a能否通过整行和整列异或可以得到矩阵b
因为元素只有0和1,所以直接将a的第一行进行相应异或变成b的第一行,然后根据第一行各列的异或情况在每行进行相同操作,最后判断a是否与b相同(需要特判一下a中如果整行与b不同也满足要求)

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=1e9+7;   

string x[1007],y[1007];
int a[1007];

int main(){ 
    IO;
    int t=1;
    cin>>t;
    while(t--){
        memset(a,0,sizeof(a));
        int n;
        cin>>n;
        for (int i = 0; i < n; ++i)
        {
            cin>>x[i];
        }
        for (int i = 0; i < n; ++i)
        {
            cin>>y[i];
        }
        for (int i = 0; i < n; ++i)
        {
            if(x[0][i]==y[0][i])continue;
            a[i]=1;
        }
        for (int i = 0; i < n; ++i)
        {
            for (int j = 0; j < n; ++j)
            {
                x[i][j]^=a[j];
            }
        }int flag=0;
        for (int i = 0; i < n; ++i)
        {
            for (int j = 0; j < n; ++j)
            {
                if(x[i][j]!=y[i][j]){
                    flag++; 
                }
            }if(flag){
                if(flag==n){
                    flag=0;
                    continue;
                }else break;
            }
        }if(!flag)cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
}

G. Strange Beauty

找到最大的序列其中任意两个数都存在整除关系,可以考虑从大到小找,每个数都从它的倍数中找到出现次数最大的,然后往下递推。因为每一个数都是从它的倍数中取得最大值,从而保证得到的序列中每一个大数都是小数的倍数。

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=1e9+7;    

int a[N],dp[N];
map<int,int>mp;

int main(){ 
    IO;
    int t=1;
    cin>>t;
    while(t--){ 
        int n;
        cin>>n; 
        mp.clear();
        for (int i = 1; i <= n; ++i)
        {
            cin>>a[i];
            mp[a[i]]++; 
        } 
        for (int i = 2e5; i > 0; --i)
        {
            dp[i]=mp[i];
            for (int j = i*2; j <= 2e5; j+=i)
            {
                dp[i]=max(dp[j]+mp[i],dp[i]);
            }
        }int ans=1e9;
        for (int i = 1; i < 2e5+1; ++i)
        {
            ans=min(ans,n-dp[i]);
            mp[i]=0;
        }cout<<ans<<endl;
    }
    return 0;
}

加油!!!

posted @ 2021-01-26 10:56  !^^!  阅读(140)  评论(0)    收藏  举报