• acwing 137. 雪花雪花雪花(hash暴力/最小表示法)


    题目大意:给N个串,问有无两个字符串有相同的循环同构串

    题解:

    方法一:hash+暴力判重
    令每个字符的和与所有字符的积的和为字符串哈希值,相同同构串的哈希值一定相等。
    然后哈希值相同串暴力判重。

    方法二:两个字符串的循环同构则最小表示法相同。

    #include<bits/stdc++.h>
    using namespace std;
    
    #define N 100009
    
    int n;
    
    int snow[7],snow_[7];
    int snows[N][7];
    int idx[N];
    
    void get_min(int a[])
    {
        int i=1,j=2,k;
        int b[13];
        for(int i=1;i<=6;i++)b[i]=a[i];
        for(int i=7;i<=12;i++) b[i]=a[i-6];
        while(i<=6&&j<=6)
        {
            for(k=0;k<6&&b[i+k]==b[j+k];k++);
            if(k==6) break;
            if(b[i+k]>b[j+k])
            {
                i+=k+1;
                if(i==j) i++; 
            }
            if(b[i+k]<b[j+k])
            {
                j+=k+1;
                if(i==j) j++;
            }
        }
        int st=min(i,j),ed;
        ed=st+6-1;
        for(int i=st;i<=ed;i++) a[i-st+1]=b[i];
    }
    
    bool cmp_arry(int a[],int b[])
    {
        for(int i=1;i<=6;i++)
        {
            if(a[i]<b[i]) return true;
            if(a[i]>b[i]) return false;
        }
        return false;
    }
    
    bool cmp(int a,int b)
    {
        return cmp_arry(snows[a],snows[b]);
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=6;j++)
            {
                scanf("%d",&snow[j]);
                snow_[6-j+1]=snow[j];
            }
            get_min(snow);
            get_min(snow_);
            if(cmp_arry(snow,snow_))
            {
                for(int gg=1;gg<=6;gg++) snows[i][gg]=snow[gg];
            }else for(int gg=1;gg<=6;gg++) snows[i][gg]=snow_[gg];
            idx[i]=i;
        /*    for(int p=1;p<=6;p++)
            {
                cout<<snow[p]<<" ";
            }
            cout<<endl;*/
        }
        
       /* for(int i=1;i<=2;i++)
        {
            for(int j=1;j<=6;j++)
            {
                cout<<snows[i][j]<<" ";
            }
            cout<<endl;
        }*/
        sort(idx+1,idx+n+1,cmp);
        for(int i=1;i<=n;i++)
        {
            if(!cmp_arry(snows[idx[i]],snows[idx[i-1]])&&!cmp_arry(snows[idx[i-1]],snows[idx[i]]))
            {
                 printf("Twin snowflakes found.");
                 return 0;
            }
        }
        printf("No two snowflakes are alike.");
        return 0;
    }
    
    #include<bits/stdc++.h>
    using namespace std;
    
    #define N 100009
    
    int n;
    
    int snow[7],snow_[7];
    int snows[N][7];
    int idx[N];
    
    void get_min(int a[])
    {
        int i=1,j=2,k;
        int b[13];
        for(int i=1;i<=6;i++)b[i]=a[i];
        for(int i=7;i<=12;i++) b[i]=a[i-6];
        while(i<=6&&j<=6)
        {
            for(k=0;k<6&&b[i+k]==b[j+k];k++);
            if(k==6) break;
            if(b[i+k]>b[j+k])
            {
                i+=k+1;
                if(i==j) i++; 
            }
            if(b[i+k]<b[j+k])
            {
                j+=k+1;
                if(i==j) j++;
            }
        }
        int st=min(i,j),ed;
        ed=st+6-1;
        for(int i=st;i<=ed;i++) a[i-st+1]=b[i];
    }
    
    bool cmp_arry(int a[],int b[])
    {
        for(int i=1;i<=6;i++)
        {
            if(a[i]<b[i]) return true;
            if(a[i]>b[i]) return false;
        }
        return false;
    }
    
    bool cmp(int a,int b)
    {
        return cmp_arry(snows[a],snows[b]);
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=6;j++)
            {
                scanf("%d",&snow[j]);
                snow_[6-j+1]=snow[j];
            }
            get_min(snow);
            get_min(snow_);
            if(cmp_arry(snow,snow_))
            {
                for(int gg=1;gg<=6;gg++) snows[i][gg]=snow[gg];
            }else for(int gg=1;gg<=6;gg++) snows[i][gg]=snow_[gg];
            idx[i]=i;
        /*    for(int p=1;p<=6;p++)
            {
                cout<<snow[p]<<" ";
            }
            cout<<endl;*/
        }
        
       /* for(int i=1;i<=2;i++)
        {
            for(int j=1;j<=6;j++)
            {
                cout<<snows[i][j]<<" ";
            }
            cout<<endl;
        }*/
        sort(idx+1,idx+n+1,cmp);
        for(int i=1;i<=n;i++)
        {
            if(!cmp_arry(snows[idx[i]],snows[idx[i-1]])&&!cmp_arry(snows[idx[i-1]],snows[idx[i]]))
            {
                 printf("Twin snowflakes found.");
                 return 0;
            }
        }
        printf("No two snowflakes are alike.");
        return 0;
    }
    
  • 相关阅读:
    让我自闭了两个星期的题 Hello xtCpc
    kmp 回忆训练2 poj3461
    kmp 字符串匹配
    线段树之动态开点  HDU 6183 Color it.
    两个思维
    codeforces 300E Empire Strikes Back
    codeforces1392 E Omkar and Duck
    codeforces1169D
    HDU4335 欧拉函数及降幂
    HDU2588GCD(欧拉函数)
  • 原文地址:https://www.cnblogs.com/zzyh/p/14785546.html
Copyright © 2020-2023  润新知