zoukankan      html  css  js  c++  java
  • 【奶昔队ROUND#1】

    奶昔队Round #1 热身

    (奶昔队不是真正的队,是群)

    CodeForces 435C Cardiogram

    模拟,不过我做的时候不是模拟,是计算...(写了好久,还wa了几次),现在看了别人的代码写过一份。

    #include <iostream>
    #include <algorithm>
    #define N 1005
    using namespace std;
    int n,x,y,a,h,l;
    char ma[N<<1][N];
    int main() {
        cin>>n;
        h=l=y=1000;
        for(int i=1;i<=n;i++){
            cin>>a;
            while(a--) if(i&1) ma[++y][++x]='/';
            else ma[--y][++x]='\';
            h=max(h,y);
            l=min(l,y);
            y+=i%2?1:-1;
        }
        for(int i=h;i>=l;i--){
            for(int j=1;j<=x;j++)
                if(ma[i][j])cout<<ma[i][j];
                else cout<<" ";
            cout<<endl;
        }
    }

    CodeForces 437B The Child and Set

    sum=Σlowbit(x),x不超过limit。

    贪心,把1到limit的所有lowbit求出来,按lowbit值从大到小排个序,每次取完一个就把sum减去一个数。

    #include <iostream>
    #include <algorithm>
    #define lowbit(x) ((x)&-(x))
    using namespace std;
    int sum,limit,ans;
    struct num{
        int id,low,ok;
    }a[100005];
    int cmp(num a,num b){
        return a.low>b.low;
    }
    int main() {
        cin>>sum>>limit;
        for(int i=1;i<=limit;i++){
            a[i].id=i;
            a[i].low=lowbit(i);
        }
        sort(a+1,a+limit+1,cmp);
        for(int i=1;i<=limit&∑i++)
            if(a[i].low<=sum){
                a[i].ok=1;
                ans++;
                sum-=a[i].low;
            }
        if(sum==0){
            cout<<ans<<endl;
            for(int i=1;i<=limit;i++)if(a[i].ok)
                cout<<a[i].id<<" ";
        }else 
            cout<<"-1";
    }

    CodeForces 437C C - The Child and Toy

    删除每个点,就需要它相邻的点(未删除的)权值和的代价,求全部点删完后的最小代价。

    贪心,一定是删权值最大的点,那么删掉时,对于相邻的边,就是花费了较小的相邻点的权值,于是直接对每条边取小的点加起来。

    #include <iostream>
    #include <algorithm>
    #define N 1005
    using namespace std;
    int n,m,ans,v[N],a,b;
    int main() {
        cin>>n>>m;
        for(int i=1;i<=n;i++)
            cin>>v[i];
        for(int i=1;i<=m;i++){
            cin>>a>>b;
            ans+=min(v[a],v[b]);
        }
        cout<<ans;
        
    }

     奶昔队Round #1

    CodeForces 527A A. Playing with Paper

    问一张纸能分多少个尽量大的正方形

    #include <iostream>
    using namespace std;
    long long a,b,ans;
    int main(){
        cin>>a>>b;
        while(a%b){
            ans+=a/b;
            a%=b;
            swap(a,b);
        }
        cout<<ans+a/b;
    }

    CodeForces 526A B. King of Thieves

    就是找5个相距固定的*,居然把字符串从1开始,智障了。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int ok(char c){
        return c=='*';
    }
    char s[10000];
    int main() {
        int n;
        cin>>n;
        cin>>s;
        for(int l=1;l<=n;l++){
            for(int j=0;j<n;j++){
                int ans=ok(s[j]);
                for(int a=1;a<=4;a++)
                if(!ok(s[j+l*a]))ans=0;
                if(ans){
                    puts("yes");
                    return 0;
                }
            }
        }
        puts("no");
        return 0;
    }

    CodeForces 526B C. Om Nom and Dark Park

    从叶子节点往根的方向,每两个兄弟的差值加到答案上,父节点的值加上较大的那个儿子的值。

    #include <iostream>
    using namespace std;
    int n,a[1<<11],ans;
    int main() {
        cin>>n;
        for(int i=2;i<(1<<(n+1));i++)
            cin>>a[i];
        for(int k=n;k;k--)
            for(int i=(1<<k);i<(1<<(k+1));i+=2){
                a[i>>1]+=max(a[i],a[i+1]);
                ans+=max(a[i],a[i+1])-min(a[i],a[i+1]);
            }
        cout<<ans<<endl;
    }

    CodeForces 526C D. Om Nom and Candies

     红糖果和蓝糖果均有开心值和重量,要总质量不超过c,开心值最大有多少。

    • 如果b更划得来,那么吃相同重量时,会选择b,于是r的数量就会小于wb;反之,则b的数量会小于wr。
    •  wr*i+wb*j≤c,如果wr>√c,那么i<√c,如果wb>√c,那么j<√c,直接枚举就行了,否则,wb和wr就都小于√c。
    #include <iostream>
    #define ll long long
    using namespace std;
    ll c,hr,hb,wr,wb,ans;
    int main() {
        cin>>c>>hr>>hb>>wr>>wb;
        if(wr>=c/wr||hr*wb<wr*hb&&wb<c/wb)
        {
            swap(wb,wr);
            swap(hb,hr);
        }
        for(int i=0;i*i<=c&&i<=c/wb;i++)
            ans=max(ans,(c-i*wb)/wr*hr+i*hb);
        cout<<ans;
    }

      

    CodeForces 526D  E. Om Nom and Necklace

    对于n(<=100万)位的字符串,问你每个前缀是否可以划分为ABAB..ABA的形式,其中A、B代表字符串(A或B可以为空),且B出现m次。

    这种题目很不好想,对于我来说。

    当前前缀P=SSSSS...SST=m个AB+1个A,AB一定是几个S组成,A为P的后缀

    共有R个S,分到m组里,余下的则是A的前缀。

    A里面有R%m个S

    B里面有R/m-R%m个S

    KMP算出循环节长度len=i-Next[i],则

    循环次数R=i/len

    如果i%len==0,代表全为S,算出来如果B为空也是可以的,

    否则,B为空不可以。

    #include <cstdio>
    #define N 1000005
    using namespace std;
    
    char s[N];
    int n,m,Next[N],ans[N];
    int main() {
        scanf("%d%d%s",&n,&m,s);
        int k=-1,i=0;
        Next[i]=k;
        while(s[i])
            if(k==-1||s[i]==s[k]){
                Next[++i]=++k;
                int len=i-Next[i],R=i/len;
                if(i%len==0)
                    ans[i]=(R/m-R%m>=0);
                else
                    ans[i]=(R/m-R%m>0);
            }else k=Next[k];
        for(int i=1;i<=n;i++)
            printf("%d",ans[i]);
        puts("");
    }

    CodeForces 526E F. Transmitting Levels

    对于100万个数围成的环,求最少能切几段,每段的和不超过b,有q次询问。

    滑窗,from[i]表示from[i]到i是已经划分了的段,ans[i]表示from[i]到i的最少段数。

    左端为j,右端为i。

    一开始j到i为一段,如果超过b,j右移,这样就求出i为右端的最大的一段,然后i右移,

    from[i]=from[j],ans[i]=ans[j]+1;相当于j结尾后面又划分了一段。

    继续求直到i-from[i]≥n。

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    
    typedef long long ll;
    
    using namespace std;
    const int MAXN = 1000000+10;
    
    int a[MAXN*2];
    int from[MAXN * 2], ans[MAXN * 2];
    ll ss[MAXN*2];
    
    int main(){
        int n, q;
        scanf("%d%d", &n, &q);
        for(int i=1;i<=n;i++){
            scanf("%d", &a[i]);
            a[i+n] = a[i];
            from[i]=i;
            ans[i]=0;
        }
        for(int i=1;i<=2*n;i++) ss[i]=ss[i-1]+a[i];
    
        
        for(int Q=1;Q<=q;Q++){
            int lim;
            scanf("%d", &lim);
            memset(ans, 0, sizeof(ans));
            //memset(from, 0, sizeof(from));
            int j = 1;
            for(int i=n+1;i<=2*n;i++){
                while(ss[i]-ss[j]>lim) j++;
                ans[i] = ans[j]+1;
                from[i] = from[j];
                if(i-from[i]>=n){
                    printf("%d
    ", ans[i]);
                    break;
                }
            }
            //printf("%d
    ", ans[2*n]);
        }
    
    }

      

  • 相关阅读:
    hive sql 解析json
    解决华为手机无法安装未签名apk问题(该安装包未包含任何证书)
    对马尔科夫决策过程的代码补充解释
    对马尔科夫决策过程MDP(Markov Decision Processes)的一点理解
    使用Web在PC和安卓之间传输文件(Transfer files via wifi)
    记录下自己的生活状态,昏昏沉沉的半年,迷茫的未来
    __repr__和pass在python中的含义
    LaTeX基础调节,调节行距,字体大小,字体,页边距
    LaTeX怎么让一行中的一部分右对齐
    Tkinter主动刷新(强制刷新)
  • 原文地址:https://www.cnblogs.com/flipped/p/5840848.html
Copyright © 2011-2022 走看看