zoukankan      html  css  js  c++  java
  • HGOI2010816 (NOIP 提高组模拟赛 day1)

    Day1 210pts(含T1莫名的-10pts和T3莫名的-30pts)

    100+70+40=210

    rank 29

    这道题第一眼看是字符串匹配问题什么KMP啊,又想KMP不会做啊,那就RK Hash 吧,结果Hash打了一半发现Hint:要全排列,

    然后掐指一算3000!一定爆所以换思路,对于区间[l,r]字符种类和对应数目与前面那个串完全相同就是一个匹配,常数是52,应该能过

    # include <bits/stdc++.h>
    using namespace std;
    char a[3005],b[3000005];
    int sta[120],stb[120],lena,lenb;
    int fun(char ch)
    {
        if ('A'<=ch&&ch<='Z') return ch-'A'+1;
        else return ch-'a'+1+26;
    }
    bool check()
    {
        for (int i=1;i<=52;i++)
          if (sta[i]!=stb[i]) return false;
        return true;
    }
    int main()
    {
        freopen("mayan.in","r",stdin);
        freopen("mayan.out","w",stdout);
        int t1,t2; scanf("%d%d",&t1,&t2);
        getchar();
        for (int i=1;i<=t1;i++) a[i]=getchar(); getchar();lena=t1;
        for (int i=1;i<=t2;i++) b[i]=getchar(); getchar();lenb=t2;
        for (int i=1;i<=lena;i++) {sta[fun(a[i])]++;}
        int ans=0;
        for (int i=1;i<=lenb;i++) {
            if (i<=lena-1) { stb[fun(b[i])]++;continue;} 
            else if (i==lena) { 
                stb[fun(b[i])]++;
                if (check()) ans++;
                continue;
            }
            stb[fun(b[i-lena])]--; stb[fun(b[i])]++;
            if (check()) ans++;
        }
        printf("%d
    ",ans);
        return 0;
    }

    事情是这样的,求形如(a...a)(b....b)或(a.....a)的子序列个数

    如abba中{a,b,ab,bb,ba,abb,bba}有且有7个

    于是考场上写出20行的STL代码,70分!跟我一起念:STL大法好qwq

    70pts(MLE/TLE)

    # include <bits/stdc++.h>
    using namespace std;
    set<string>stt; string s;
    int main()
    {
        freopen("strange.in","r",stdin); 
        freopen("strange.out","w",stdout);
        cin>>s; 
        int len=s.length();
        char ch1,ch2;
        for (int i=0;i<len;i++) {
            ch1=s[i]; int j=i; 
            while (j<len&&s[j]==ch1) { j++; stt.insert(s.substr(i,j-i));}
            ch2=s[j];
            while (j<len&&s[j]==ch2) { j++; stt.insert(s.substr(i,j-i));}
        }    
        int ans=0,i;
        printf("%d
    ",stt.size()); 
        return 0;
    }

    好了讲正解,vector[i][j]表示形如(i....i)(j....j)的二元组(x,y)表示有x个i,y个j组成,然后就会对于每个vecort都会有二元组,然后面积求和即可

    然后把所有面积的并集求出来就是vector[i][j]的值,然后把各值求出来累加就行了。

    # include <bits/stdc++.h>
    using namespace std;
    struct Node{
        int x,y;
    };
    vector <Node> a[27][27];
    Node m[200005];
    int n;
    bool cmp(Node aa,Node bb)
    {
        if (aa.x!=bb.x) return aa.x>bb.x;
        else return aa.y>bb.y;
    }
    char s[200005];
    int fun()
    {
        sort(m+1,m+1+n,cmp);
        int X=m[1].x,Y=m[1].y;
        int S=X*Y;
        for (int i=2;i<=n;i++) 
         if (m[i].y>Y) {
             S=S+(m[i].y-Y)*m[i].x;
             X=m[i].x;Y=m[i].y;
         }
         return S;
    }
    int main()
    {
        scanf("%s",s+1); 
        int len=strlen(s+1);
        int i;
        for (i=1;i<=len;i++) {
            char ch1,ch2;
            int cnt1=0,cnt2=0;
            ch1=s[i];  int j=i;
            while (j<=len&&s[j]==ch1) j++,cnt1++;
            if (j>len) j=len; ch2=s[j];
            int kk=j-1;
            while (j<=len&&s[j]==ch2) j++,cnt2++;
            if (ch1==ch2) continue;
            Node N; N.x=cnt1; N.y=cnt2;
            a[ch1-'a'+1][ch2-'a'+1].push_back(N);
            i=kk;
        }
        int ans=0;
        for (int i=1;i<=26;i++)
         for (int j=1;j<=26;j++)
          {
              n=(int)(a[i][j].size());
              memset(m,0,sizeof(m));
            for (int k=1;k<=n;k++) m[k]=a[i][j][k-1];
              ans=ans+fun();
         }
         for (int i=1;i<=26;i++) {
             int cnt=0,maxx=0;
             bool flag=false;
             for (int j=1;j<=len;j++) if (s[j]==i+'a'-1) flag=true;
             for (int j=1;j<=len;j++) {
                 while (s[j]==i+'a'-1&&s[j+1]==i+'a'-1&&j<len) j++,cnt++;
                 maxx=max(maxx,cnt);
                 cnt=0; 
             }
            if (flag)ans=ans+maxx+1; 
         } 
          printf("%d
    ",ans);
        return 0;
    }

    std:

    #include <bits/stdc++.h>
    using namespace std;
    template <typename T> void read(T &t) {
        char ch=getchar(); int f=1; t=0;
        while ('0'>ch||ch>'9') { if (ch=='-') f=-1; ch=getchar(); }
        do { (t*=10)+=ch-'0'; ch=getchar(); } while ('0'<=ch&&ch<='9'); t*=f;
    }
    typedef long long ll;
    const int maxn=100010;
    int n,k,x[maxn],a[maxn],sz;
    map<int,int> m;
    ll ans;
    int main() {
        read(n); read(k);
        for (int i=1;i<=n;i++) {
            read(x[i]); m[x[i]]++;
        }
        sort(x+1,x+(n+1));
        for (int i=1;i<=n;i++)
            if (x[i]!=x[i-1]) a[++sz]=x[i];
        int pos=0,c1=0,c2=0;
        for (int i=1;i<=sz;i++) {
            while (pos<sz&&a[pos+1]<=(ll)a[i]*k) {
                pos++;
                if (m[a[pos]]>=2) c1++;
                else c2++;
            }
            int v=0;
            if (m[a[i]]>=2) v++;
            int s=c1+c2-1;
            ans+=3*(c1-v);
            if (s>1) ans+=3LL*s*(s-1);
            if (m[a[i]]>=2) ans+=3*(c1+c2-1);
            if (m[a[i]]>=3) ans++;
            if (m[a[i]]>=2) c1--; else c2--;
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    python(内置高阶函数)
    cms 环境搭建
    cookie、session 和 token 区别
    接口用例设计
    python(字符编码与转码)
    从北斗卫星时钟(北斗校时器)发展纵论世界卫星导航新格局
    北斗授时系统(GPS授时设备)错一秒会怎样?京准电子科技
    北斗校时服务器(GPS时钟服务器)在电力调度系统应用
    GPS卫星时钟(北斗授时设备)在监狱管理系统方案
    NTP校时(网络对时服务器)IPC网络摄像机时钟同步
  • 原文地址:https://www.cnblogs.com/ljc20020730/p/9488376.html
Copyright © 2011-2022 走看看