Educational Codeforces Round 90 (Rated for Div. 2)

Donut Shops

 CodeForces - 1373A 

题意:两家货店,一家a元一件,一家b件c元,求买多少到第一家绝对划算,买多少到第二家绝对划算,

考虑  b ==1时,直接判断平均单价即可。

当   第一个的平均单价小于第二个的平均单价,第一个绝对优势,因为可以拆开卖。

  第一个的平均单价等于第二个的平均单价,c只会 > a   

                     没有相等情况

  第一个的平均单价大于于第二个的平均单价 且a>=c   第一个没戏

                      a<c  买一件第一个满足,  

#include<bits/stdc++.h>
using namespace std;
const int N=6e2+500;
typedef long long ll;
int main(){
    int t;scanf("%d",&t);
    while(t--){
        ll a,b,c,ans1=0,ans2=0;
        cin>>a>>b>>c;
        // scanf("%lld %lld %lld",&a,&b,&c);
        double p1=a*1.0,p2=c*1.0/b;
        if(b==1){
            if(p1==p2)ans1=ans2=-1;
            else if(p1>p2)ans1=-1,ans2=1;
            else ans1=1,ans2=-1;
        }
        else {
            if(p1<p2){
                ans1=1,ans2=-1;
            }
            else if(p1==p2){
                if(a>c)ans1=-1,ans2=b;
                else if(a<c)ans1=1,ans2=-1;
            }
            else if(p1>p2){
                if(a<c)ans1=1,ans2=b;
                else if(a>c)ans1=-1,ans2=b;
                else if(a==c)ans1=-1,ans2=b;
            }
        }
        cout<<ans1<<" "<<ans2<<endl;
        // cout<<ans1<<" "<<ans2<<endl;
    }
    // system("pause");

    return 0;
}
View Code

01 Game

 CodeForces - 1373B 

无脑题,暴力删除

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        string s;
        cin>>s;
        int cnt=0;
        while(1){
            int len=s.size();
            bool flag=0;
            for(int i=0;i<len;i++){
                if(i!=len-1&&s[i]!=s[i+1]){
                    flag=1;
                    cnt++;
                    s.erase(i,2);
                    break;
                }
            }
            if(!flag)break;
        }
        if(cnt%2)puts("DA");
        else puts("NET");

    }    

    // system("pause");
    return 0;
        
}
View Code

Pluses and Minuses

 CodeForces - 1373C 

给出一段代码,要求模拟伪代码过程,直接模拟TLE,观察代码效果

对于一个给定的只含 +  - 字符串,由0开始枚举一个step,遇 + 则+ ,遇 - 则  - ,小于0就退出;答案为所有步数的和。

暴力枚举O(n^n),考虑如下做法:

从左到右枚举,遇到0就加上这个步数,然后cnt清零,最后走完加一个len。

实际上在cur<0的时候,必然会枚举到一个点进过,加上这个距离。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
    int t;scanf("%d",&t);
    while(t--){
        string s;
        cin>>s;
        ll ans=0,cur=0;
        int len=s.size();
        for(int i=0;i<len;i++){
            if(s[i]=='+')cur++;
            else cur--;
            if(cur<0){
                ans+=i+1;
                cur=0;
            }
        }
        ans+=len;
        cout<<ans<<endl;
    }



    // system("pause");
    return 0;
}
View Code

Maximum Sum on Even Positions

 CodeForces - 1373D 

题意:对于一个给定的序列,可以旋转一个子区间,求偶数项和最大。下标从0开始。

首先考虑  旋转长度为奇数没有意义,

旋转长度为偶数时:  1  , 首项为偶项:

          翻转每个奇项对答案贡献为 a(i+1) -  ai   求一个最大连续和。

          2,  首项为奇项:

           翻转每个奇项对答案贡献为 ai- a(i+1)   求一个最大连续和。

二者取大

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+50;
ll a[N];
int main(){
    int t,n;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        ll maxx=0,sum1=0,sum2=0,ans=0;        
        
        for(int i=0;i<n;i++){
            cin>>a[i];
            if(!(i%2))ans+=a[i];
        }

        for(int i=1;i<n;i+=2){
            if(i<n-1)sum1=max(0ll,sum1+a[i]-a[i+1]);
            maxx=max(maxx,sum1);
        }

        for(int i=0;i<n;i+=2){
            if(i<n-1)sum2=max(0ll,sum2+a[i+1]-a[i]);
            maxx=max(maxx,sum2);
        }
        // cout<<"ans :";
        cout<<maxx+ans<<endl;

    }


    // system("pause");
    return 0;
        
}
View Code

Sum of Digits

 CodeForces - 1373E 

题意  给定一个n,k  。 求一个 x 使得        f(x)+f(x+1)++f(x+k)=nf(x)+f(x+1)+⋯+f(x+k)=n.

f(x)为十进制的数字和。

考虑k<=9  那么进位最多一次。

不进位的情况下:f(x+1)=f(x)+1.    进位实际上减去若干个9 。

设有 t 个受进位影响。影响的9的个数为   i  。

那么有    (k+1) f(x)   +k *(k+1)/ 2  -  9 * t * i    =  n

考虑 t  实际上 受枚举x的个位影响,那么实际上枚举 x 的 个位 和 i  即可 推出  f(x)

对于一个给定的f (x)要求 i 个9受到影响,x要最小,贪心构造即可。

复杂度O (40)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll inf=2e18;
ll cur,n,k,ans;

bool build(ll fx,ll i,ll x){
    vector<ll>v;
    v.push_back(x);fx-=x;
    if(fx<0)return 0;

    for(int p=1;p<i;p++){
        fx-=9;
        if(fx<0)return 0;
        v.push_back(9);
    }
    
    if(fx>=8){fx-=8;v.push_back(8);}
    
    while(fx>=9){fx-=9;v.push_back(9);}
    
    if(fx>0)v.push_back(fx);
    cur=0;
    ll cnt=1;
    
    for(int p=0;p<v.size();p++){
        cur+=v[p]*cnt;
        cnt*=10;
    }

    // if(x==4)cout<<"path : "<<cur<<endl;
    return 1;

}

int main(){
    int t;scanf("%d",&t);
    while(t--){
        scanf("%lld %lld",&n,&k);
        ll t,fx;
        n-=k*(k+1)/2;
        // cout<<"ans : ";
        if(n<0){cout<<-1<<endl;continue;}
        ans=inf;
        for(ll x=0;x<=9;x++){
            if(x+k>=10)t=(x+k)%10+1;
            else t=0;
            for(ll i=1;i<=30;i++){
                if((n+9*t*i)%(k+1))continue;
                fx=(n+9*t*i)/(k+1);
                if(fx<x)continue;
                // if(x==4&&t==2)cout<<"yes"<<endl;
                if(!build(fx,i,x)){
                    // cout<<"false"<<endl;
                    continue;
                }
                // cout<<"true"<<endl;
                ans=min(ans,cur);
            }
        }

        if(ans!=inf)printf("%lld\n",ans);
        else printf("-1\n");

    }

    // system("pause");
    return 0;
}
View Code

Network Coverage

 CodeForces - 1373F

题意   n  个村庄构成一个环,每个村庄要求 ai,每两个村庄有一个站bi,  问是否可以满足每个村庄 ai 的需要。

最大流水不过

考虑第一个站,分配给第一个村庄x,剩下的贪心构造,满足上面的,剩下的全给下面的,然后从第n个村庄留下来的为c,

那么分配给第一个村庄实际上为  f (x)= x + c

考虑 x 减少 1 ,实际 c 增加小于1,f ( x )  随着 x 减小而减小,满足单调性。

x增大,c减小,f(x)增大,求得一个c>=0 的 x  的最大解,直接二分即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=1e6+60;
int n;
ll a[N],b[N];
ll check(ll x){
    ll out=b[1]-x,need,pos;
    need=a[2]-out;
    for(int i=2;i<=n;i++){
        // if(i==n)pos=
        need=a[i]-out;
        if(need<0)need=0;
        out=b[i]-need;
        if(out<0)return -1ll;
    }    
    return out;
}
int main(){
        int t;scanf("%d",&t);
        while(t--){
            scanf("%d",&n);
            for(int i=1;i<=n;i++)scanf("%d",&a[i]);
            for(int i=1;i<=n;i++)scanf("%d",&b[i]);
            ll l=0,r=b[1];
            
            while(l<=r){
                ll mid=(l+r)/2;
                if(check(mid)>=0){
                    l=mid+1;
                }
                else r=mid-1;
            }

            if(r<0)puts("NO");
            else if(check(r)+r>=a[1])puts("YES");
            else puts("NO");

        }

    // system("pause");
    return 0;
}
View Code

 

posted @ 2020-06-28 21:42  无声-黑白  阅读(151)  评论(0编辑  收藏  举报