1. 程式人生 > 實用技巧 >Educational Codeforces Round 90 (Rated for Div. 2)

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