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;
}
posted @ 2021-05-19 16:07  ANhour  阅读(98)  评论(0编辑  收藏  举报