How many---hdu2609(最小表示)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2609

给你n个01串,然后求这n个串中有几个不同的;

例如:1100 ,1001 ,0011 ,0110,这4个串都是相同的,因为他们可以通过移动得到;

我们可以通过最大最小表示法来求出串的最小字典序所对应的串,那么上面的四个串对应的都是0011,这样一来就可以很轻松的求出结果了;

后面的我们可以用把每次求得串插入到Trie树中,如果树中已经存在此串,那么就返回0,不存在就返回1;

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
using namespace std;

const int N = 2e4+7;
char s[N], s0[N];

struct node
{
    node* next[2];
};

int Min_Index(char a[], int n)
{
    int i=0, j=1, k=0;
    while(i<n && j<n && k<n)
    {
        int t = a[(i+k)%n] - a[(j+k)%n];
        if(t == 0)
            k++;
        else
        {
            if(t < 0)
                j = j + k + 1;
            else
                i = i + k + 1;
            if(i == j)
                j++;
            k=0;
        }
    }
    return min(i, j);
}
int Tire(char a[], node* head)
{
    int flag = 0;
    node *p = head;
    for(int i=0; a[i]; i++)
    {
        int k = a[i]-'0';
        if(p->next[k]==NULL)
        {
            flag = 1;///建立字典树,如果a已经存在返回0,否则返回1,加到结果中去;
            p->next[k] = new node();
        }
        p = p->next[k];
    }
    return flag;
}
void FreeTire(node *head)///没有用到,但是还是留着当个知识点吧,释放内存;
{
    node *p = head;

    for(int i=0; i<2; i++)
    {
        if(p->next[i] != NULL)
            FreeTire(p->next[i]);
    }
    free(p);
}

int main()
{
    int n, ans, len, Min;
    node*head;
    while(scanf("%d", &n)!=EOF)
    {
        head = new node();
        ans = 0;
        for(int i=1; i<=n; i++)
        {
            scanf("%s", s0);
            len = strlen(s0);

            strcpy(s, s0);
            strcat(s, s0);

            Min = Min_Index(s, len);
            memset(s0, 0, sizeof(s0));
            strncpy(s0, s+Min, len);

            ans+=Tire(s0, head);
        }
        printf("%d
", ans);

    /// FreeTire(head);

    }
    return 0;
}
View Code


不用字典树:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
using namespace std;

const int N = 110;
char s[N], s0[N], ss[N*N][N];

int Min_Index(char a[], int n)
{
    int i=0, j=1, k=0;
    while(i<n && j<n && k<n)
    {
        int t = a[(i+k)%n] - a[(j+k)%n];
        if(t == 0)
            k++;
        else
        {
            if(t < 0)
                j = j + k + 1;
            else
                i = i + k + 1;
            if(i == j)
                j++;
            k=0;
        }
    }
    return min(i, j);
}
int cmp(const void *p1, const void *p2)
{
    return strcmp((char *)p1, (char *)p2);
}
int main()
{
    int n, ans, len, Min, k;
    while(scanf("%d", &n)!=EOF)
    {
        if(n==0)
        {
            printf("0
");
            continue;
        }
        k = 0;
        for(int i=1; i<=n; i++)
        {
            scanf("%s", s0);
            len = strlen(s0);

            strcpy(s, s0);
            strcat(s, s0);

            Min = Min_Index(s, len);
            memset(s0, 0, sizeof(s0));
            strncpy(s0, s+Min, len);
            s0[len] = '';
            strcpy(ss[k], s0);
            k++;
        }
        qsort(ss, k, sizeof(ss[0]), cmp);
        ans = 1;
        for(int i=1; i<k; i++)
        {
            if(strcmp(ss[i], ss[i-1])!=0)
                ans++;
        }
        printf("%d
", ans);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zhengguiping--9876/p/4846254.html