Codeforces Round #643 (Div.2)

前言:这套cf我感觉出的很不错,AB就不说了,唯一有点欠缺的就是C和D的位置应该换一下,C出的挺不错,反正我当时没有想出来(赛后补题的时候其实也不难。。听朋友说还可以FFT优化,然而我是个图论手并不会数论)。D就是个一眼构造题,也没什么意思。E也是个不错的三分题,至少加强了我对三分的认知。F过的人太少,不补了叭

A:Sequence with Digits

签到题不详细讲了,直接上代码吧...

#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long 
 
ll a, b;
 
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        cin >> a >> b;
        int cnt = 1;
        while (1)
        {
            if (cnt == b)
                break;
            int ma = 0, mi = 9;
            ll tmp = a;
            while (tmp > 0)
            {
                int now = tmp % 10;
                ma = max(ma, now), mi = min(mi, now);
                tmp /= 10;
            }
            if (mi == 0)
                break;
            cnt++;
            a += mi * ma;
        }
        cout << a << "\n";
    }
}
View Code

B:Young Explorers

这个题也没什么意思,签到

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e6+5;
int a[maxn];
int main(){
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
        }
        sort(a+1,a+n+1);
        int res=0;int sum=0;
        for(int i=1;i<=n;i++)
        {
            sum++;
            if(a[i]<=sum)
            {
                sum=0;res++;
            }
        }
        cout<<res<<endl;
    }
}
View Code

C:Count Triangles

解法:很显然,这个题2层for循环肯定爆TLE,那么就需要优化了。众所周知,构成三角形的条件是:x+y>z,那么我可以进行枚举x+y来优化,令m=x+y,算出当x+y和为m的时候,有几种可行的构造数量s2,然后去乘s1=max(m-1,d)-c+1就可以了,前提是s1和s2均非0

∵x+y=m, ∴y=m-x, 又∵B≤y=m-x≤C,∴m-C≤x≤m-B,又因为A≤x≤B,所以取交集,该组数目等于右界-左界+1

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=5e5+5;
int main(){
    int a,b,c,d;cin>>a>>b>>c>>d;
    ll ans=0;
    for(int i=a+b;i<=b+c;i++){
        int s1=min(d,i-1)-c+1;
        int s2=min(i-b,b)-max(i-c,a)+1;
        if(s1<0||s2<0) continue;
        else ans+=1LL*s1*s2;
    }
    cout<<ans<<endl;
}
View Code

D. Game With Array

解法:构造n-1个1和1个s-n+1,判断s-n+1>n的情况是否存在,存在就输出yes,反之输出no

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e6+5;
int a[maxn];
int main(){
    int n,s;cin>>n>>s;
    if(s<=2*n-1) puts("NO");
    else{
        puts("YES");
        for(int i=1;i<n;i++){
            cout<<1<<" ";
        }
        cout<<s-n+1<<endl;
        cout<<s-n<<endl;
    }
}
View Code

E. Restorer Distance

解法:三分高度,因为这个题是求最小花费,所以图像是与y=x^2很类似,针对曲线求最小值就是三分。另外up就是需要增加的砖块数,down就是需要减少的砖块数。显然总花费=ans=A*up+R*down;倘若A+R>M,那么就需要减少总花费了,此时x=min(up,down),ans+=M*x-x*A-x*R;

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e5+5;
int N,A,R,M,a[maxn];
ll check(int mid){
    ll ans=0,up=0,down=0;
    rep(i,1,N){
        if(a[i]<mid)up+=mid-a[i];
        else down+=a[i]-mid;
    }
    ans=A*up+R*down;
    ll x=min(up,down);
    if(A+R>M) ans+=M*x-x*A-x*R;
    return ans;
}
int main(){
    cin>>N>>A>>R>>M;
    rep(i,1,N) cin>>a[i];
    int l=0,r=1e9;
    while(l<r){
        int midl=(r-l)/3+l,midr=r-(r-l)/3;
        ll suml=check(midl),sumr=check(midr);
        if(suml>sumr) l=midl+1;
        else r=midr-1;
    }
    ll ans=check(l);
    cout<<ans<<endl;
}
View Code

 

posted @ 2020-05-17 12:38  Anonytt  阅读(316)  评论(0编辑  收藏  举报