zoukankan      html  css  js  c++  java
  • Codeforces Round #452 (Div. 2)

    第一场补题AK场(纪念一下下

    A:给你N个数 求最多怎么分类使和为3的个数最多 

    水题直接分类讨论即可

    #include <bits/stdc++.h>
    #define N 200005
    using namespace std;
    int main(){
        int n;cin>>n;
        int cnt1=0;int cnt2=0;
        int t;
        for(int i=1;i<=n;i++) {
            cin>>t;
            if(t==1) cnt1++;
            else cnt2++;
        }
        int ans=0;
        if(cnt2>cnt1){
            cout<<cnt1<<endl;
            return 0;
        }
        else{
            ans+=(cnt2);
            cnt1-=cnt2;
            ans+=(cnt1/3);
            cout<<ans<<endl;
            return 0;
        }
        return 0;
    } 

    B:给你N个数字 问这些数字可不可能是一年中连续出现的月份(可能是闰年)

    (from sb红) 由n<24可知,输入的的月份最多跨三个年份,由此可以构造出一个连续年中的月份天数表,只要将输入序列与表相比较,匹配则输出YES,反之NO。

    关于表的构造:第一种是比赛的时候写的那种,分1无闰年,2第一年闰,3第二年闰,4第三年闰四种情况。第二种是构造一个长度为六年的表(如:闰平平平闰平)即可包括第一种的所有情况。
    关于匹配:都是常数级别直接暴力匹配即可,闲的无聊可以用KMP优化匹配 
    #include<bits/stdc++.h>
    using namespace std;
    int a[30];
    int b[10][36]={{31,28,31,30,31,30,31,31,30,31,30,31,   31,28,31,30,31,30,31,31,30,31,30,31,   31,28,31,30,31,30,31,31,30,31,30,31,}
    ,{31,29,31,30,31,30,31,31,30,31,30,31,   31,28,31,30,31,30,31,31,30,31,30,31,   31,28,31,30,31,30,31,31,30,31,30,31,}
    ,{31,28,31,30,31,30,31,31,30,31,30,31,   31,29,31,30,31,30,31,31,30,31,30,31,   31,28,31,30,31,30,31,31,30,31,30,31,}
    ,{31,28,31,30,31,30,31,31,30,31,30,31,   31,28,31,30,31,30,31,31,30,31,30,31,   31,29,31,30,31,30,31,31,30,31,30,31,}};
    int main()
    {
        int n,k;
        bool ans=false;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        for(int i=0;i<4;i++)
            for(int j=0;j<36;j++)
            {
                if(a[0]==b[i][j])
                {
                    for(k=1;k<n;k++)
                        if(a[k]!=b[i][k+j])
                            break;
                    if(k==n) ans=true;
                }
            }
        if(ans) printf("YES
    ");
        else printf("NO
    ");
        return 0;
    }

    C:给一个数字n 问如何对1-n这个数字进行分类 使两类和的绝对值之差最小 输出这个最小值 并输出任意一类的数字

    题解:贪心题 从后往前 判断这个数加入哪一堆 只需要模拟这个过程最符合条件即可

    #include <bits/stdc++.h>
    using namespace std;
    int ab(int a,int b){
    	int t=a-b;
    	if(t>0) return t;
    	else return -1*t;
    }
    int main(){
    	int n;cin>>n;
    	int cnt1=0;int cnt2=0;
    	vector<int>v1;vector<int>v2;
    	for(int i=n;i>=1;i--){
    		if(cnt1==cnt2){
    			v1.push_back(i);cnt1+=i;
    		}
    		else if(ab(cnt1+i,cnt2)<ab(cnt2+i,cnt1)){
    			v1.push_back(i);cnt1+=i;
    		}
    		else{
    			v2.push_back(i);cnt2+=i;
    		}
    	}
    	cout<<ab(cnt1,cnt2)<<endl;
    	cout<<v1.size();
    	for(int i=0;i<v1.size();i++){
    		cout<<" "<<v1[i];
    	}
    	cout<<endl;
    	return 0;
    }
    

    D:form(jlz)

    思路就是先根据n+(n-1)找出满足条件的最大末尾连续9的个数,比如50就是99,最大就是两个9,只有99满足,而1到50中相加能等于99就只有50+49,即min(n-99/2,99/2)
    可以看出当n+n-1={9,99,999,9999,99999,999999,9999999,99999999,999999999}时为1;
    当n+n-1<9时为n*(n-1)/2;
    其余情况则保持9的个数为最大,将首位从本来的数枚举到0,然后每次对枚举的那个数(假设为x&&x<n+n-1
    )算出min(n-x/2,x/2),比如对于12来说,12+11=23,枚举首位从2到0
    1.x=29,29>23,继续枚举,x=19,19<23,则ans+=min(12-19/2,19/2),继续枚举,x=9<23,则ans+=min(12-9/2,9/2);最后ans=3+4=7
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define N 1000010
    ll n,s,weishu,ans,shouwei,tt;
    ll qaq[]={9,99,999,9999,99999,999999,9999999,99999999,999999999};
    void cal(){
        for(int i=0;i<9;i++){
            if(s==qaq[i]){
                cout<<1<<endl;
                exit(0);
            }
        } 
        tt=upper_bound(qaq,qaq+9,s)-qaq;
        if(tt==0){
            cout<<n*(n-1)/2<<endl;
            exit(0);
        }
        else
        tt=qaq[tt-1];
        ll aa=s;
        while(aa){
            weishu++;
            if(aa<10)
            shouwei=aa;
            aa/=10;
        }
    }
    int main(){
        while(cin>>n){
            weishu=0,shouwei=0,tt=0,ans=0;
            s=2*n-1;
            cal();
            for(int i=shouwei;i>=0;i--){
                ll qq=i;
                for(int j=weishu;j>1;j--){
                    qq*=10;
                }
                qq+=tt;
                if(qq>s){
                    continue;
                }
                ans+=min(n-qq/2,qq/2);
            }
            cout<<ans<<endl;
        }
        return 0;
    } 

    E:题意:给你n个数 每次去掉连续次数最多的一串数(如果有多个 应优先删除靠左边的)

    直接线段树合并维护最长连续区间 对于已经删除的区间不进行合并即可 细节挺多,对拍好久找出WA点

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #define ll long long
    #define N 200005
    using namespace std;
    typedef struct node{
    	int l,r,l2,r2;
        ll l1;ll r1;int len1;int len2;int len;int id;int id1;
        int flag;
    }node;
    node d[N<<2];
    ll a[N];
    void push(int root){
        if(d[root].flag==1){
           d[root<<1].l1=0;d[root<<1].r1=0;d[root<<1].len1=0;d[root<<1].len2=0;d[root<<1].len=0;d[root<<1].id=d[root<<1].l;d[root<<1].id1=d[root<<1].r;
           d[root<<1|1].l1=0;d[root<<1|1].r1=0;d[root<<1|1].len1=0;d[root<<1|1].len2=0;d[root<<1|1].len=0;d[root<<1|1].id=d[root<<1|1].l;d[root<<1|1].id1=d[root<<1|1].r;
           d[root<<1].flag=1;d[root<<1|1].flag=1;d[root].flag=0;
        }
    }
    void up(int root){
    	if(d[root<<1].l1==0&&d[root<<1|1].l1==0){
    		d[root].l1=0;d[root].r1=0;d[root].len=0;d[root].len1=0;d[root].len2=0;d[root].id=d[root<<1].l;
    		d[root].id1=d[root<<1|1].r;
    		return ;
    	}
    	else if(d[root<<1].l1==0){
    		d[root]=d[root<<1|1];
    		return ;
    	}
    	else if(d[root<<1|1].r1==0){
    		d[root]=d[root<<1];
    		return ;
    	}
        d[root].l1=d[root<<1].l1;d[root].r1=d[root<<1|1].r1;
        d[root].l=d[root<<1].l;d[root].r=d[root<<1|1].r;
        d[root].l2=d[root<<1].l2;d[root].r2=d[root<<1|1].r2;
        if(d[root<<1].len>=d[root<<1|1].len){
            d[root].len=d[root<<1].len;d[root].id=d[root<<1].id;
            d[root].id1=d[root<<1].id1;
        }
        else {
            d[root].len=d[root<<1|1].len;d[root].id=d[root<<1|1].id;
            d[root].id1=d[root<<1|1].id1;
        }
        //cout<<d[root<<1].r2<<"====="<<d[root<<1|1].l2<<endl;
        if(d[root<<1].r1==d[root<<1|1].l1){
            if(d[root<<1].len2+d[root<<1|1].len1>=d[root].len){
            	if(d[root<<1].len2+d[root<<1|1].len1==d[root].len){
            		d[root].id=min(d[root<<1].r2,d[root].id);
            		d[root].id1=min(d[root<<1|1].l2,d[root].id1);
    			}
    			else{
                d[root].id=d[root<<1].r2;
                d[root].id1=d[root<<1|1].l2;}
                d[root].len=d[root<<1].len2+d[root<<1|1].len1;
            }
            if(d[root<<1].l2==d[root<<1].r) {
            d[root].l2=d[root<<1|1].l2;
    		d[root].len1=d[root<<1].len1+d[root<<1|1].len1;}
            else d[root].len1=d[root<<1].len1;
            if(d[root<<1|1].r2==d[root<<1|1].l) {
    		d[root].r2=d[root<<1].r2;
    		d[root].len2=d[root<<1|1].len2+d[root<<1].len2;
    	}
            else d[root].len2=d[root<<1|1].len2;
        }
        else{
            d[root].len1=d[root<<1].len1;d[root].len2=d[root<<1|1].len2;
        }
     //   cout<<d[root].l<<"=================="<<d[root].r<<" "<<d[root].r2<<endl;
    }
    void built(int root,int l,int r){
        if(l==r){
        	d[root].l=l;d[root].r=r;d[root].l2=l;d[root].r2=r;
            d[root].l1=a[l];d[root].r1=a[l];d[root].len1=1;d[root].len2=1;d[root].len=1;d[root].id=l;
            d[root].flag=0;d[root].id1=l;
            return ;
        }
        int mid=(l+r)>>1;
        built(root<<1,l,mid);
        built(root<<1|1,mid+1,r);
        d[root].l=d[root<<1].l;d[root].r=d[root<<1|1].r;
        d[root].flag=0;
        up(root);
    }
    void update(int root,int l,int r,int t,int l1,int r1){
        if(l<=l1&&r1<=r){
            d[root].flag=1;
            d[root].l1=0;d[root].r1=0;d[root].len1=0;d[root].len2=0;d[root].len=0;
            d[root].id=d[root].l;d[root].id1=d[root].r;
            return ;
        }
        push(root);
        int mid=(l1+r1)>>1;
        if(l<=mid) update(root<<1,l,r,t,l1,mid);
        if(r>mid) update(root<<1|1,l,r,t,mid+1,r1);
        up(root);
       // cout<<d[root].l<<" "<<d[root].r<<" "<<d[root].id<<" "<<d[root].id1<<endl;
      //  cout<<d[root].l<<"======"<<d[root].r<<" "<<d[root<<1|1].len1<<" "<<d[root<<1].r2<<" "<<d[root<<1|1].l2<<endl;
    }
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
        built(1,1,n);
        int ans=0;
        while(d[1].len!=0){
        	ans++;
         //	cout<<d[1].id<<" "<<d[1].id1<<" "<<d[1].len<<endl;   	
        	update(1,d[1].id,d[1].id1,1,1,n);
    
    	}
    	printf("%d
    ",ans);
        return 0;
    }
    

     F:给定n个字符 m次操作 每次删除l r区间内出现的字符ch

       题解:线段树裸题维护

    #include <bits/stdc++.h>
    #define N 200005
    using namespace std;
    typedef struct node{
        int sum;int cnt[62];bool flag[62];
    }node;
    node d[N<<2];
    int vis[N];
    int read(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return f*x;
    }
    void up(int root){
        d[root].sum=d[root<<1].sum+d[root<<1|1].sum;
        for(int i=0;i<62;i++) d[root].cnt[i]=d[root<<1].cnt[i]+d[root<<1|1].cnt[i];
    }
    void built(int root,int l,int r){
        if(l==r){
            d[root].sum=1;d[root].cnt[vis[l]]=1;
            return ;
        }
        int mid=(l+r)>>1;
        built(root<<1,l,mid);
        built(root<<1|1,mid+1,r);
        up(root);
    }
    void push(int root){
        for(int i=0;i<62;i++){
            if(d[root].flag[i]){
                d[root<<1].sum-=d[root<<1].cnt[i];
                d[root<<1].cnt[i]=0;d[root<<1].flag[i]=1;
                d[root<<1|1].sum-=d[root<<1|1].cnt[i];
                d[root<<1|1].cnt[i]=0;d[root<<1|1].flag[i]=1;
                d[root].flag[i]=0;            
            }
        }
    }
    void update(int root,int l,int r,int l1,int r1,int t){
        if(d[root].cnt[t]==0) return ;
        if(l<=l1&&r1<=r){
            d[root].flag[t]=1;d[root].sum-=d[root].cnt[t];
            d[root].cnt[t]=0;
            return ;
        }
        int mid=(l1+r1)>>1;
        push(root);
        if(l<=mid) update(root<<1,l,r,l1,mid,t);
        if(r>mid) update(root<<1|1,l,r,mid+1,r1,t);
        up(root);
    }
    int ans1;
    void querty1(int root,int l,int r,int e){
        if(l==r){
            ans1=l;
            return ;
        }
        int mid=(l+r)>>1;
        push(root);
        if(e<=d[root<<1].sum) querty1(root<<1,l,mid,e);
        else querty1(root<<1|1,mid+1,r,e-d[root<<1].sum);
        up(root);
    }
    void querty2(int root,int l,int r){
        if(d[root].sum==0)  return ;
        if(l==r){
            for(int i=0;i<62;i++){
                if(d[root].cnt[i]==1){
                    ans1=i;break;
                }
            }
            if(ans1>=0&&ans1<=9) printf("%c",'0'+ans1);
            else if(ans1>=10&&ans1<=35) printf("%c",'A'+ans1-10);
            else printf("%c",'a'+ans1-36);    
            return ;
        }
        int mid=(l+r)>>1;
        push(root);
        querty2(root<<1,l,mid);
        querty2(root<<1|1,mid+1,r);
        up(root); 
    }
    int main(){
        int n,m;
        n=read();m=read();
        char ch;
        for(int i=1;i<=n;i++){
            scanf(" %c",&ch);
            if(ch>='0'&&ch<='9') vis[i]=ch-'0';
            else if(ch>='A'&&ch<='Z') vis[i]=ch-'A'+10;
            else vis[i]=ch-'a'+36;
         }
         built(1,1,n);int l,r;
         for(int i=1;i<=m;i++){
             l=read();r=read();scanf("%c",&ch);
             int t;
             if(ch>='0'&&ch<='9') t=ch-'0';
            else if(ch>='A'&&ch<='Z') t=ch-'A'+10;
            else t=ch-'a'+36;
            querty1(1,1,n,l);l=ans1;
            querty1(1,1,n,r);r=ans1;
            update(1,l,r,1,n,t);
         }
        querty2(1,1,n);
        puts("");
        return 0;
    }
  • 相关阅读:
    Window下安装redis
    Redhat安装python环境(readline模块)
    Golang之hello,beego
    Golang之go 命令用法
    Golang之Mysql事务
    Golang之waitgroup用法
    记录java版本不兼容的坑,(kafka运行报错)
    位运算的技巧(有拓展的技巧)
    关于单片机软件框架的一点思考
    解决main.o(.data) type RW incompatible with bsp.o(.ARM.__AT_0x24001000) type ZI in er RW_IRAM2.(转载)
  • 原文地址:https://www.cnblogs.com/wang9897/p/8066773.html
Copyright © 2011-2022 走看看