zoukankan      html  css  js  c++  java
  • [USACO 2017 Open Gold] Tutorial

    Link:

    传送门

    A:

    由于每个颜色只染色一次就确定了所有要染色的区间

    要求染色的次数其实就是求区间最多嵌套多少层,如果有区间相交则无解

    以上操作明显可以将左端点排序后用栈来维护

    #include <bits/stdc++.h>
    
    using namespace std;
    #define X first
    #define Y second
    #define pb push_back
    typedef double db;
    typedef long long ll;
    typedef pair<int,int> P;
    const int MAXN=2e5+10;
    struct node{int x,d,col;};
    node dat[MAXN];int st[MAXN],top;
    int n,x,l[MAXN],r[MAXN],cur,res,tot;
    bool cmp(node a,node b){return a.x==b.x?a.d<b.d:a.x<b.x;}
    
    int main()
    {
        scanf("%d",&n);
        memset(l,0x3f,sizeof(l));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            l[x]=min(l[x],i),r[x]=max(r[x],i);
            if(!x) dat[++tot]=node{i,0,0};
        }
        for(int i=1;i<=n;i++)
            if(r[i]) dat[++tot]=node{l[i],0,i},dat[++tot]=node{r[i],1,i};
        sort(dat+1,dat+tot+1,cmp);
        
        for(int i=1;i<=tot;i++)
        {//注意0代表没有颜色要特殊处理 
            if(!dat[i].col)
            {
                if(top) return puts("-1"),0;
                else continue;
            }
            if(!dat[i].d)
                st[++top]=dat[i].col,cur++;
            else
            {
                if(dat[i].col!=st[top])
                    return puts("-1"),0;
                top--;cur--;
            }
            res=max(res,cur);
        }
        printf("%d",res);
        return 0;
    }
    Problem A

    注意零代表没有颜色要特殊处理……

    B:

    涉及字符串匹配想到哈希,结果一开始写成了$O(n^3*log(n))$

    由于最外层的字符串长度的可行性是单调的,二分后可优化为$O(n^2*log(n)^2)$

    但上述的复杂度是可以继续优化的

    使用$two pointers$来利用单调性,每次可行就移动左端点,否则移动右端点

    这样可以只检验$2*n$个字符串,复杂度降到了$O(2*n^2*log(n))$

    同时该题也可以每次暴力构造$Trie$树来进行匹配,复杂度为$O(n^3)$

    #include <bits/stdc++.h>
    
    using namespace std;
    #define X first
    #define RG register
    #define Y second
    #define pb push_back
    typedef double db;
    typedef long long ll;
    typedef pair<int,int> P;
    typedef unsigned long long ull;
    const int MAXN=1e3+10,base=233;
    ull hs[MAXN][MAXN],pre[MAXN];
    int n,m,f;char s[MAXN];
    map<ull,int> mp;
    
    bool check(int x)
    {
        for(int i=x;i<=m;i++)
        {
            mp.clear();f=1;
            for(RG int k=1;k<=n;k++)
                mp[hs[k][i]-hs[k][i-x]*pre[x]]=1;
            for(RG int k=n+1;k<=2*n;k++)
                if(mp[hs[k][i]-hs[k][i-x]*pre[x]]){f=0;break;}
            if(f) return true;
        }
        return false;
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        pre[0]=1;
        for(RG int i=1;i<=m;i++) pre[i]=pre[i-1]*base;
        for(RG int i=1;i<=2*n;i++)
        {
            scanf("%s",s+1);
            for(RG int j=1;j<=m;j++)
                hs[i][j]=hs[i][j-1]*base+(s[j]-'A');
        }
        
        int l=1,r=m;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(check(mid)) r=mid-1;
            else l=mid+1;
        }
        printf("%d",l);
        return 0;
    }
    Problem B

    $two pointers$对比二分的优越之处就在于其能更及时的纠错

    如果当前长度不行就直接加长,而二分则要将该长度的所有字符串都检验过再进行调整

  • 相关阅读:
    (转)WinForm中的各种表格控件
    sql2005 单用户改为多用户sql语句
    使用sp_executesql执行动态SQL语句,同时向里面传入参数。
    visual studio 不能创建biztalk 项目
    sql2005 无法连接服务器 1433端口没有监听,但是本地帐户可以登陆
    visual studio运行时提示无法启动应用程序
    将表中的数据生成插入语句
    sql 补零方法
    正则表达式,动态生成小数点位数的验证
    “本地计算机上的SQL SERVER服务启动后又停止了”解决方法
  • 原文地址:https://www.cnblogs.com/newera/p/9638739.html
Copyright © 2011-2022 走看看