• 18春季训练01-3/11 2015 ACM Amman Collegiate Programming Contest


    Solved   A Gym 100712A Who Is The Winner
    Solved   B Gym 100712B Rock-Paper-Scissors
    Solved   C Gym 100712C Street Lamps
    Solved   D Gym 100712D Alternating Strings
    Solved   E Gym 100712E Epic Professor
    Solved   F Gym 100712F Travelling Salesman
    Solved   G Gym 100712G Heavy Coins
    Solved   H Gym 100712H Bridges
    Solved   I Gym 100712I Bahosain and Digits
    Solved   J Gym 100712J Candy
    Solved   K Gym 100712K Runtime Error
    Solved   L Gym 100712L Alternating Strings II


    2015 ACM Amman Collegiate Programming Contes

    训练赛01,icpc赛制五小时,难度三星,最终AC:8/12 打得很菜

    A  找到最高分数同时罚时最小的就行

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+10;
    const int maxm=1e6+10;
    const int INF=0x3f3f3f3f;
    typedef long long ll;
    typedef unsigned long long ull;
    #define tpyeinput int
    inline bool read(tpyeinput &num){int flag=1,ch=getchar();if(ch==EOF) return false;num=0;while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}while(ch>='0'&&ch<='9'){num=num*10+ch-'0',ch=getchar();}num*=flag;return true;}
    inline bool read(tpyeinput &num1,tpyeinput &num2){return read(num1)&&read(num2);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3){return read(num1)&&read(num2)&&read(num3);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3,tpyeinput &num4){return read(num1)&&read(num2)&&read(num3)&&read(num4);}
    int casn,n,m,k;
    struct node {
        int a,b;
        string name;
    }x[maxn];
    int cmp(node a,node b){
        if(a.a==b.a) return a.b<b.b;
        else return a.a>b.a;
    }
    int main(){
    // #define test
    #ifdef test
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    
        read(casn);
        while(casn--){
    //        memset(x,0,sizeof x);
            read(n);
            for(int i=0;i<n;i++){
            cin>>x[i].name>>x[i].a>>x[i].b;
            }
            sort(x,x+n,cmp);
            cout<<x[0].name<<endl;
        }
    
    #ifdef test
        fclose(stdin);
        fclose(stdout);
        system("out.txt");
    #endif
        return 0;
    }
    View Code

    B 先预处理前缀和,再枚举2个分界点,复杂度n^2

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+10;
    const int maxm=2e6+10;
    const int INF=0x3f3f3f3f;
    typedef long long ll;
    typedef unsigned long long ull;
    #define tpyeinput int
    inline bool read(tpyeinput &num){int flag=1,ch=getchar();if(ch==EOF) return false;num=0;while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}while(ch>='0'&&ch<='9'){num=num*10+ch-'0',ch=getchar();}num*=flag;return true;}
    inline bool read(tpyeinput &num1,tpyeinput &num2){return read(num1)&&read(num2);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3){return read(num1)&&read(num2)&&read(num3);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3,tpyeinput &num4){return read(num1)&&read(num2)&&read(num3)&&read(num4);}
    int casn,n,m,k;
    int num[maxn];
    char s[maxn];
    int s1[maxn],s2[maxn],s3[maxn];
    int main(){
    //#define test
    #ifdef test
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    
        read(casn);
        while(casn--){
            cin>>n>>(s+1);
            for(int i=1;i<=n;i++){
                s1[i]=s1[i-1]+(s[i]=='R');
                s2[i]=s2[i-1]+(s[i]=='P');
                s3[i]=s3[i-1]+(s[i]=='S');
            }
            int ans=0;
            int mx=0;
            for(int i=0;i<=n;i++){
                for(int j=i;j<=n;j++){
                    int x=s3[i]+(s1[j]-s1[i])+(s2[n]-s2[j]);
                    x-=(s2[i])+(s3[j]-s3[i])+(s1[n]-s1[j]);
                    if(x>0){
                        ans++;
                    }
                }
            }
            cout<<ans<<endl;
        }
    #ifdef test
        fclose(stdin);
        fclose(stdout);
        system("out.txt");
    #endif
        return 0;
    }
    View Code

    C 跑两遍,注意用2个数组,不要重复计算了,方法很多,可以黑暗长度大于1就直接点亮后面一个

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+10;
    const int maxm=1e6+10;
    const int INF=0x3f3f3f3f;
    typedef long long ll;
    typedef unsigned long long ull;
    #define tpyeinput int
    inline bool read(tpyeinput &num){int flag=1,ch=getchar();if(ch==EOF) return false;num=0;while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}while(ch>='0'&&ch<='9'){num=num*10+ch-'0',ch=getchar();}num*=flag;return true;}
    inline bool read(tpyeinput &num1,tpyeinput &num2){return read(num1)&&read(num2);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3){return read(num1)&&read(num2)&&read(num3);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3,tpyeinput &num4){return read(num1)&&read(num2)&&read(num3)&&read(num4);}
    int casn,n,m,k;
    char s[maxn];
    char s2[maxn];
    int ans;
    int main(){
    //#define test
    #ifdef test
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    
      read(casn);
      while(casn--){
          cin>>n>>(s+1);
          int ans=0;
          memset(s2,'.',sizeof s2);
          for(int i=1;i<=n;i++){
              if(s[i]=='*') s2[i]=s2[i+1]=s2[i-1]='*';
          }
          for(int i=1;i<=n;i++){
              if(s2[i]==s2[i+1]&&s2[i]==s2[i+2]&&s2[i]=='.'){
                  s2[i+1]=s2[i]=s2[i+2]='*';
                  ans++;
              }else if(s2[i]=='.'){
                      s2[i+1]=s2[i]=s2[i+2]='*';
                  ans++;
              }
          }
          cout<<ans<<endl;
      }
    
    #ifdef test
        fclose(stdin);
        fclose(stdout);
        system("out.txt");
    #endif
        return 0;
    }

    D (补)

    定义dp[i]为把i合法分割的最小花费

    dp[i]可以直接转移到dp[i-1]+1

    然后遍历(i-k)到i,如果出现连续,从连续处到(i-k)都可以转移到dp[i],花费为1

    数据小,复杂度n^2可过

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e3+10;
    const int maxm=1e6+10;
    const int INF=0x3f3f3f3f;
    typedef long long ll;
    typedef unsigned long long ull;
    #define tpyeinput int
    inline bool read(tpyeinput &num){int flag=1,ch=getchar();if(ch==EOF) return false;num=0;while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}while(ch>='0'&&ch<='9'){num=num*10+ch-'0',ch=getchar();}num*=flag;return true;}
    inline bool read(tpyeinput &num1,tpyeinput &num2){return read(num1)&&read(num2);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3){return read(num1)&&read(num2)&&read(num3);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3,tpyeinput &num4){return read(num1)&&read(num2)&&read(num3)&&read(num4);}
    int casn,n,m,k;
    char s[maxn];
    int dp[maxn];
    int main(){
    //#define test
    #ifdef test
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    
        read(casn);
        while(casn--){
            read(n,k);
            scanf("%s",s+1);
            memset(dp,INF,sizeof dp);
            dp[0]=-1;
            for(int i=1;i<=n;i++){
                dp[i]=min(dp[i],dp[i-1]+1);
                int flag=0;
                for(int j=i-1;j&&i-j+1<=k;j--){
                    if(s[j]==s[j+1]) flag=1;
                    if(flag) {
                        dp[i]=min(dp[i],dp[j-1]+1);
                    }
                }
            }
            cout<<dp[n]<<endl;
        }
    
    #ifdef test
        fclose(stdin);
        fclose(stdout);
        system("out.txt");
    #endif
        return 0;
    }
    View Code

    E 所有人的中,加上(100-最小值)不低于50的有多少

    /**********************
    *@Name:
    *
    *@Author: Nervending
    *@Describtion:
    *@DateTime:
    ***********************/
    #include <bits/stdc++.h>
    #define show(x) cout<<#x<<"="<<x<<endl
    using namespace std;
    const int maxn=1e5+10;
    const int maxm=1e6+10;
    const int INF=0x3f3f3f3f;
    typedef long long ll;
    typedef unsigned long long ull;
    #define tpyeinput int
    inline bool read(tpyeinput &num){int flag=1,ch=getchar();if(ch==EOF) return false;num=0;while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}while(ch>='0'&&ch<='9'){num=num*10+ch-'0',ch=getchar();}num*=flag;return true;}
    inline bool read(tpyeinput &num1,tpyeinput &num2){return read(num1)&&read(num2);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3){return read(num1)&&read(num2)&&read(num3);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3,tpyeinput &num4){return read(num1)&&read(num2)&&read(num3)&&read(num4);}
    int casn,n,m,k;
    int num[maxn];
    bool cmp(int &a,int &b)
    {
        return  a>b;
    }
    int main(){
    //#define test
    #ifdef test
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    
        read(casn);
        while(casn--){
            read(n);
            for(int i=0;i<n;i++){
                read(num[i]);
            }
            sort(num,num+n,cmp);
            int tmp=100-num[0];
            int ans=0;
            for(int i=0;i<n;i++){
                if(num[i]+tmp>=50) ans++;
            }
            printf("%d
    ",ans);
        }
        
    #ifdef test
        fclose(stdin);
        fclose(stdout);
        system("out.txt");
    #endif
        return 0;
    }
    View Code

    F 给一个无向连通图,求最小瓶颈树的最大边是多少

    简单推导,可知最小瓶颈树就是最小生成树,就是求最小生成树的最大边

    (一开始想成了求任意两点之间的路径中的最大边...)

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+10;
    const int maxm=2e6+10;
    const int INF=0x3f3f3f3f;
    typedef long long ll;
    typedef unsigned long long ull;
    #define tpyeinput int
    inline bool read(tpyeinput &num){int flag=1,ch=getchar();if(ch==EOF) return false;num=0;while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}while(ch>='0'&&ch<='9'){num=num*10+ch-'0',ch=getchar();}num*=flag;return true;}
    inline bool read(tpyeinput &num1,tpyeinput &num2){return read(num1)&&read(num2);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3){return read(num1)&&read(num2)&&read(num3);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3,tpyeinput &num4){return read(num1)&&read(num2)&&read(num3)&&read(num4);}
    int casn,n,m,k;
    int root[maxn];
    struct node{
        int from,to,cost;
    }e[maxm];
    bool cmp(node &a,node &b){
        return a.cost<b.cost;
    }
    int ans,t;
    int find(int now){
        if(now==root[now])return now;
        else {
            return root[now]=find(root[now]);
        }
    }
    #define same(a,b) (find(a)==find(b))
    void unite(int a,int b){
        a=find(a);
        b=find(b);
        if(a==b)return ;
        else root[a]=b;
    }
    void init(){
        for(int i=0;i<maxn;i++){
            root[i]=i;
        }
        memset(e,0,sizeof e);
    }
    void kruskal(){
        sort(e,e+m,cmp);
        for(int i=0;i<m;i++){
            node t=e[i];
            if(!same(t.from,t.to)){
                unite(t.from,t.to);
                ans=max(t.cost,ans);
            }
        }
    }
    int main(){
    //#define test
    #ifdef test
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    
        read(casn);
        while(casn--){
            read(n,m);
            init();
            int cnt=0;
            for(int i=0;i<m;i++){
                int a,b,c;
                read(a,b,c);
                e[cnt++]=(node){a,b,c};
                e[cnt++]=(node){b,a,c};
            }
            m=cnt;
            ans=0;
            kruskal();
            cout<<ans<<endl;
        }
    
    #ifdef test
        fclose(stdin);
        fclose(stdout);
        system("out.txt");
    #endif
        return 0;
    }
    View Code

    G 排个序之后直接暴力枚举所有的可能性,枚举过程中的选择用位压缩就行

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+10;
    const int maxm=1e6+10;
    const int INF=0x3f3f3f3f;
    typedef long long ll;
    typedef unsigned long long ull;
    #define tpyeinput int
    inline bool read(tpyeinput &num){int flag=1,ch=getchar();if(ch==EOF) return false;num=0;while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}while(ch>='0'&&ch<='9'){num=num*10+ch-'0',ch=getchar();}num*=flag;return true;}
    inline bool read(tpyeinput &num1,tpyeinput &num2){return read(num1)&&read(num2);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3){return read(num1)&&read(num2)&&read(num3);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3,tpyeinput &num4){return read(num1)&&read(num2)&&read(num3)&&read(num4);}
    int casn,n,m,k;
    int num[maxn];
    int main(){
    //#define test
    #ifdef test
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    
        read(casn);
        while(casn--){
            read(n,m);
            memset(num,0xc0,sizeof num);
            for(int i=0;i<n;i++){
                read(num[i]);
            }
            sort(num,num+n);
            int ans=0;
            for(int i=1;i<1<<n;i++){
                int s=0,mn=INF,cnt=0,mx=0,flag=1;
                for(int j=0;j<n;j++){
                    if((i>>j)&1)
                        s+=num[j],mx=max(num[j],mx),cnt++;
                }
                if(s>=m){
                    for(int j=0;j<n;j++){
                        if((i>>j)&1) if(s-num[j]>=m) flag=0;
                    }
                    if(flag) ans=max(ans,cnt);
                }
                
            }
            cout<<ans<<endl;
        }
    
    #ifdef test
        fclose(stdin);
        fclose(stdout);
        system("out.txt");
    #endif
        return 0;
    }
    View Code

    H (补)

    把图进行双连通分量把图缩成一颗树,在新图中用两次dfs找到树的直径,然后答案就是强连通分量的数量-直径-1

    (好久没写tarjan+缩点,懵逼了)

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+10;
    const int maxm=1e6+10;
    const int INF=0x3f3f3f3f;
    typedef long long ll;
    typedef unsigned long long ull;
    #define tpyeinput int
    inline bool read(tpyeinput &num){int flag=1,ch=getchar();if(ch==EOF) return false;num=0;while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}while(ch>='0'&&ch<='9'){num=num*10+ch-'0',ch=getchar();}num*=flag;return true;}
    inline bool read(tpyeinput &num1,tpyeinput &num2){return read(num1)&&read(num2);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3){return read(num1)&&read(num2)&&read(num3);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3,tpyeinput &num4){return read(num1)&&read(num2)&&read(num3)&&read(num4);}
    struct node {int to,cost,next;}e[maxm],e2[maxm];int head[maxn],head2[maxn],nume,nume2;
    void add(int a,int b,int c=1,node *eg=e,int &ne=nume,int hd[]=head){eg[++ne]=(node){b,c,hd[a]};hd[a]=ne;}
    int casn,n,m,k;
    int low[maxn],dfn[maxn],stk[maxn];
    int ins[maxn];
    int top,numc,numd,belong[maxn];
    
    void tjdfs(int now,int pre) {
        dfn[now]=low[now]=++numd;
        stk[++top]=now;
        ins[now]=1;
        for(int i=head[now]; i; i=e[i].next) {
            int to=e[i].to;
            if(to==pre)continue;
            if(ins[to]==0) tjdfs(to,now);
            low[now]=min(low[now],low[to]);
        }
        if(low[now]==dfn[now]) {
            numc++;
            do {
                belong[stk[top]]=numc;
                ins[stk[top]]=-1;
            } while(stk[top--]!=now);
        }
    }
    void tjmake(){
        for(int i=1;i<=n;i++){
            int a=belong[i];
            for(int j=head[i];j;j=e[j].next){
                int to=e[j].to;
                int b=belong[to];
                if(a==b) continue;
                add(a,b,1,e2,nume2,head2);
                add(b,a,1,e2,nume2,head2);
            }
        }
    }
    inline void tjinit(){
        numc=nume2=numd=0;
        top=-1;
        memset(ins,0,sizeof ins);
        memset(dfn,0,sizeof dfn);
        memset(head2,0,sizeof head);
        memset(belong,0,sizeof belong);
        memset(low,0,sizeof low);
        memset(stk,0,sizeof stk);
    }
    inline void tarjan(){
        tjinit();
        for(int i=1;i<=n;i++) if(ins[i]==0){
             tjdfs(i,-1);
        }
        tjmake();
    }
    int vis[maxn],cnt=0,pos,ans;
    void dfs(int now,int dep=0){
        vis[now]=1;
        if(dep>cnt){
            cnt=dep;
            pos=now;
        }
        for(int i=head2[now];i;i=e2[i].next){
            int to=e2[i].to;
            if(!vis[to]) dfs(to,dep+1);
        }
    }
    int main(){
    //#define test
    #ifdef test
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
        read(casn);
        while(casn--){
            read(n,m);
            memset(head,0,sizeof head);
            nume=0;
            for(int i=0;i<m;i++){
                int a,b;read(a,b);
                add(a,b);
                add(b,a);
            }
            tarjan();
            memset(vis,0,sizeof vis);
            cnt=0;
            pos=1;
            dfs(1);
            memset(vis,0,sizeof vis);
            cnt=0;
            dfs(pos);
            cout<<numc-cnt-1<<endl;;
        }
    
    #ifdef test
        fclose(stdin);
        fclose(stdout);
        system("out.txt");
    #endif
        return 0;
    }
    View Code

    I (补)

    暴力枚举最终到达的数字,由于只需要找到最大可行解,但是可行解不具有单调性,所以只能从n开始遍历k长

    复杂度10*n^2,一开始10*n^3的算法T了,

    然后用一个数组和一个变量维护改变量,复杂度可以降阶,就ac了

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=3e2+10;
    const int maxm=1e6+10;
    const int INF=0x3f3f3f3f;
    typedef long long ll;
    typedef unsigned long long ull;
    #define tpyeinput int
    #define show(x) cout<<#x<<"="<<x<<endl
    inline bool read(tpyeinput &num){int flag=1,ch=getchar();if(ch==EOF) return false;num=0;while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}while(ch>='0'&&ch<='9'){num=num*10+ch-'0',ch=getchar();}num*=flag;return true;}
    inline bool read(tpyeinput &num1,tpyeinput &num2){return read(num1)&&read(num2);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3){return read(num1)&&read(num2)&&read(num3);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3,tpyeinput &num4){return read(num1)&&read(num2)&&read(num3)&&read(num4);}
    int casn,n,m;
    char s[maxn];
    int add[maxn];
    int t[maxn];
    int main(){
    #define test
    #ifdef test
        freopen("in.txt","r",stdin);
    //    freopen("out.txt","w",stdout);
    #endif
    
        read(casn);
        while(casn--){
            scanf("%s",s+1);
            int f=0;
            int len=strlen(s+1);
            for(int k=len;k>1;k--){
                for(int i=0;i<10;i++){
                    memset(add,0,sizeof add);
                    for(int j=1;j<=len;j++) t[j]=s[j]-'0';
                    int tmp=0;
                    for(int j=1;j+k-1<=len;j++){
                            tmp-=add[max(j-k,0)];
                            int y=0;
                            t[j]=(t[j]+tmp)%10;
                            if(t[j]==i) continue;
                            if(i>t[j]) y=(i-t[j]);
                            else y=(i+10-t[j]);
                            add[j]=y;
                            t[j]=i;
                            tmp+=y;
                    }
                    int flag=1;
                    for(int j=len-k+2;j<=len;j++){
                        tmp-=add[max(j-k,0)];
                        if((t[j]+tmp)%10!=i){
                            flag=0;
                            break;
                        }
                    }
                    if(flag){
                        printf("%d
    ",k);
                        f=1;
                        break;
                    }
                }
                if(f) break;
            }
            if(f==0) puts("1");
        }
    
    #ifdef test
        fclose(stdin);
    //    fclose(stdout);
    //    system("out.txt");
    #endif
        return 0;
    }
    View Code

    J 桶排序记录蜡烛数量和年龄人数,遍历统计即可

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+10;
    const int maxm=1e6+10;
    const int INF=0x3f3f3f3f;
    typedef long long ll;
    typedef unsigned long long ull;
    #define tpyeinput int
    inline bool read(tpyeinput &num){int flag=1,ch=getchar();if(ch==EOF) return false;num=0;while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}while(ch>='0'&&ch<='9'){num=num*10+ch-'0',ch=getchar();}num*=flag;return true;}
    inline bool read(tpyeinput &num1,tpyeinput &num2){return read(num1)&&read(num2);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3){return read(num1)&&read(num2)&&read(num3);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3,tpyeinput &num4){return read(num1)&&read(num2)&&read(num3)&&read(num4);}
    int casn,n,m,k;
    int num[maxn],s[maxn];
    int main(){
    //#define test
    #ifdef test
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    
        read(casn);
        while(casn--){
            read(n,m);
            int mx=0,mx2=0;
            memset(num,0,sizeof num);
            memset(s,0,sizeof s);
            for(int i=0;i<n;i++){
                int k;read(k);
                s[k]++;
                mx2=max(k,mx2);
            }
    
            for(int i=0;i<m;i++) {
                int k;read(k);
                num[k]++;
                mx=max(k,mx);
            }
            int cnt=0;
            int ans=1;
            for(int i=5;i<=mx2;i++){
                while(cnt<=mx&&num[cnt]<s[i]) cnt++;
                if(cnt>mx){
                    ans=0;
                    break;
                }
                if(s[i]) cnt++;
    
            }
            cout<<(ans?"YES":"NO")<<endl;
        }
    
    #ifdef test
        fclose(stdin);
        fclose(stdout);
        system("out.txt");
    #endif
        return 0;
    }
    View Code

    K 标记数组记录是否存在,然后遍历数组,是否k/x存在

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+10;
    const int maxm=1e6+10;
    const int INF=0x3f3f3f3f;
    typedef long long ll;
    typedef unsigned long long ull;
    #define tpyeinput int
    inline bool read(tpyeinput &num){int flag=1,ch=getchar();if(ch==EOF) return false;num=0;while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}while(ch>='0'&&ch<='9'){num=num*10+ch-'0',ch=getchar();}num*=flag;return true;}
    inline bool read(tpyeinput &num1,tpyeinput &num2){return read(num1)&&read(num2);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3){return read(num1)&&read(num2)&&read(num3);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3,tpyeinput &num4){return read(num1)&&read(num2)&&read(num3)&&read(num4);}
    int casn,n,m,k;
    int vis[maxn];
    int num[maxn];
    int main(){
    // #define test
    #ifdef test
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    
        read(casn);
        while(casn--){
            read(n,k);
            memset(vis,0,sizeof vis);
            for(int i=0;i<n;i++){
                read(num[i]);
                vis[num[i]]++;
            }
            sort(num,num+n);
            int flag=0;
            for(int i=0;i<n&&num[i]*num[i]<=k&&flag==0;i++){
                if(num[i]==0) continue;
                if(k%num[i]==0){
                    if(num[i]*num[i]==k&&vis[num[i]]>=2){
                        cout<<num[i]<<' '<<num[i]<<endl;
                        flag=1;
                    }
                    else if(num[i]*num[i]!=k&&vis[k/num[i]]){
                        cout<<num[i]<<' '<<k/num[i]<<endl;
                        flag=1;
                    }
                }
            }
            if(!flag) cout<<-1<<endl;
        }
    
    #ifdef test
        fclose(stdin);
        fclose(stdout);
        system("out.txt");
    #endif
        return 0;
    }
    View Code

    L (补)

    把D题的数据范围扩大了1000倍

    解法依然是DP,n^2无法过 考虑n^2以下的算法

    思路:

    1.外层循环->无法减少 

    2.找到(i-k)到i之间的最早连续位置需要低于O(n)->预处理找到i之前的不连续长度达到O(1)询问

    3.找到(dp[i-k]到dp[i-pos])之间的最小值,pos为最后一个连续处也需要低于O(n)->线段树维护DP数组,O(logn)查询最小值

    最后在单点更新dp[i]处的答案即可

    复杂度nlogn

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+10;
    const int maxm=1e6+10;
    const int INF=0x3f3f3f3f;
    typedef long long ll;
    typedef unsigned long long ull;
    #define tpyeinput int
    inline bool read(tpyeinput &num){int flag=1,ch=getchar();if(ch==EOF) return false;num=0;while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}while(ch>='0'&&ch<='9'){num=num*10+ch-'0',ch=getchar();}num*=flag;return true;}
    inline bool read(tpyeinput &num1,tpyeinput &num2){return read(num1)&&read(num2);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3){return read(num1)&&read(num2)&&read(num3);}
    inline bool read(tpyeinput &num1,tpyeinput &num2,tpyeinput &num3,tpyeinput &num4){return read(num1)&&read(num2)&&read(num3)&&read(num4);}
    int casn,n,m,k;
    char s[maxn];
    int ans;
    int lst[maxn<<3];
    int num[maxn];
    #define mid ((l+r)>>1)
    int rmin(int s,int t,int l=0,int r=n,int now=1){
        if(l>r||t<l||s>r) return INF;
        if(s<=l&&t>=r) return lst[now];
        return min(rmin(s,t,l,mid,now<<1),rmin(s,t,mid+1,r,now<<1|1));
    }
    void upd(int pos,int x,int l=0,int r=n,int now=1){
        if(l>r||pos<l||pos>r) return;
        lst[now]=min(x,lst[now]);
        if(l==r) return;
        upd(pos,x,l,mid,now<<1);
        upd(pos,x,mid+1,r,now<<1|1);
    }
    int main(){
    //#define test
    #ifdef test
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    
        read(casn);
        while(casn--){
            read(n,k);
            scanf("%s",s+1);
            ans=0;
            memset(lst,INF,sizeof lst);
            memset(num,0,sizeof num);
            #define show(x) cout<<#x<<"="<<x<<endl
            for(int i=1;i<=n;i++){
                 if(s[i]!=s[i-1]) num[i]=num[i-1]+1;
                 else num[i]=1;
            }
            upd(0,0);
            for(int i=1;i<=n;i++){
                ans++;
                if(i-num[i]>=max(i-k,0)+1)
                    ans=min(ans,rmin(max(i-k,0),i-num[i]-1)+1);
                upd(i,ans);
            }
            cout<<ans-1<<endl;
        }
    
    #ifdef test
        fclose(stdin);
        fclose(stdout);
        system("out.txt");
    #endif
        return 0;
    }
    View Code
  • 相关阅读:
    springIOC 原理
    jeesite异步分页
    yum
    乐观锁原理
    equlas(),hashcode(),hashset,hashmap
    链接收藏
    java单词
    jeesite优化
    SailingEase .NET Resources Tool (.NET 多语言资源编辑器)转
    C#基本语法
  • 原文地址:https://www.cnblogs.com/nervendnig/p/8573233.html
Copyright © 2020-2023  润新知