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

    D题:直接滑窗,枚举转折点,滑动结束点。水题啊水题。。。。

    #include<bits/stdc++.h>
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define MS0(a) memset(a,0,sizeof(a))
    #define PII pair<int,int>
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=1000100;
    const int INF=1e9+10;
    
    int n,a,b,T;
    char s[maxn],t[maxn];
    int look[maxn];
    
    int solve(int dir)
    {
        if(dir) reverse(s+2,s+n+1);
        REP(i,1,n) look[i]=s[i]=='w'?b+1:1;
        int ans=0;
        int cost=look[1],cnt=1;
        int x=1,y=n+1;
        /// find the last y
        while(y>1){
            y--;
            if(y==1){
                y++;break;
            }
            cost+=a+look[y];
            cnt++;
            if(cost>T){
                cnt--,cost-=a+look[y],y++;
                break;
            }
        }
        //cout<<"cnt="<<cnt<<" cost="<<cost<<" T="<<T<<endl;
        if(cost<=T) ans=max(ans,cnt);
        /// solve
        for(x=1;;){
            if(x+1==y) break;
            x++;
            cost+=2*a+look[x];
            cnt++;
            while(y<=n&&cost>T){
                cost-=look[y]+a;
                cnt--;
                y++;
            }
            if(cost<=T) ans=max(ans,cnt);
        }
        return ans;
    }
    
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("in.txt","r",stdin);
        #endif // ONLINE_JUDGE
        while(cin>>n>>a>>b>>T){
            scanf("%s",s+1);
            int ans=0;
            REP(i,0,1) ans=max(ans,solve(i));
            cout<<ans<<endl;
        }
        return 0;
    }
    
    /**
    4 2 3 10
    wwhw
    
    5 2 4 13
    hhwhh
    
    5 2 4 1000
    hhwhh
    
    3 1 100 10
    whw
    
    */
    View Code

    E题:贪心+并查集。

    将所有数拿出来从小到大排序,按顺序填进去,第一个肯定是填1,接着用如果当前要填的数为x,看x的所在行和所在列,要填的x必然大于等于所在行和所在列的最大值,如果大于的话很好处理,取最大值+1就可以了,关键在于等于的时候。这里用并查集维护,将在同一行或同一列相等的数用并查集连通起来,那么每次只要需要更新的时候只要更新并查集的祖先就可以了,反正无论找哪个都会找到它的祖先。而如果某个数在同行同列没有相等的,那么它的祖先就是它自己了。现在问题就解决了,每添加一个数,检查同行同列有没有相等的,如果有更新并查集的祖先或它,并将它和祖先连起来,如果没有直接更新就行了。分四种情况代码会比较清晰一些。

    #include<bits/stdc++.h>
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define MS0(a) memset(a,0,sizeof(a))
    #define PII pair<int,int>
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=1000100;
    const int INF=1e9+10;
    
    int n,m;
    int a[maxn];
    PII b[maxn];int N;
    int fa[maxn];
    int val[maxn];
    int rid[maxn],cid[maxn];/// 行最大值的位置,列最大值的位置
    
    int find(int x)
    {
        return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("in.txt","r",stdin);
        #endif // ONLINE_JUDGE
        while(cin>>n>>m){
            REP(i,1,n) REP(j,1,m) scanf("%d",&a[(i-1)*m+j]);
            REP(i,1,n) fa[i]=i;
            N=n*m;
            REP(i,1,N) b[i]={a[i],i};
            sort(b+1,b+N+1);
            REP(i,1,N) fa[i]=i;
            MS0(val);
            MS0(rid);MS0(cid);
            int p1=b[1].second;
            int r1=(p1-1)/m+1,c1=p1%m;
            if(c1==0) c1=m;
            val[p1]=1;
            rid[r1]=cid[c1]=p1;
            REP(i,2,N){
                int p=b[i].second;
                int r=(p-1)/m+1,c=p%m;
                if(c==0) c=m;
                int x=find(rid[r]),y=find(cid[c]);
                if(a[p]>a[x]&&a[p]>a[y]){
                    rid[r]=cid[c]=p;
                    val[p]=max(val[x],val[y])+1;
                }
                else if(a[p]>a[x]&&a[p]==a[y]){
                    rid[r]=p;
                    val[p]=max(val[x]+1,val[y]);
                    fa[y]=p;
                }
                else if(a[p]==a[x]&&a[p]>a[y]){
                    cid[c]=p;
                    val[p]=max(val[x],val[y]+1);
                    fa[x]=p;
                }
                else{
                    rid[r]=cid[c]=p;
                    val[p]=max(val[x],val[y]);
                    fa[x]=p;fa[y]=p;
                }
            }
            REP(i,1,n){
                REP(j,1,m){
                    int x=find((i-1)*m+j);
                    printf("%d ",val[x]);
                }
                puts("");
            }
        }
        return 0;
    }
    
    /**
    2 2
    1 2
    3 4
    
    4 3
    20 10 30
    50 40 30
    50 60 70
    90 80 70
    
    1 1
    1
    2 2
    2 2
    2 2
    
    4 3
    7 8 8
    5 1 4
    3 2 8
    4 5 4
    
    */
    View Code
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    你应该知道的77条 Windows 7小技巧
    Platform Builder: Build Tools Intro
    JavaScript面向对象编程实现研究
    优秀驾驶员开车技巧
    WinCE BSP中的Dirs文件和Sources文件
    WinCE BSP中的Dirs文件和Sources文件
    WIX资源
    男性减肥方法!!!!!(转)
    Platform Builder: Sources.cmn
    批处理中的字符串处理详解
  • 原文地址:https://www.cnblogs.com/--560/p/5256429.html
Copyright © 2011-2022 走看看