码迷,mamicode.com
首页 > 其他好文 > 详细

How many - HDU 2609 (trie+最小表示)

时间:2015-08-19 19:49:24      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:

题目大意:有 N 个手链,每个手链的最大长度不超过100,求出来最多有多少个不同的手链。
 
分析:因为手链是可以转动的,所以只要两个手链通过转动达到相同,那么也被认为是一种手链,然而如果每次都循环比较的话无疑是非常浪费时间的,不过如果把每个串都用最小的字典序表示出来,那么同样的手链肯定会变成相同的状态,比如第二组数据
 
原串    最小表示法(字典序最小的串)
1010 --> 0101
0101 --> 0101
1000 --> 0001
0001 --> 0001
 
这样就比较容易判断是否相同了,可以使用字典树来判断这个串是否出现过。
 
代码如下:
==========================================================================================================
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
using namespace std;

const int MAXM = 2;
const int MAXN = 1007;

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

bool BuildTrie(node *head, char s[])
{///建立字典树,如果s已经存在返回0,否则返回1
    node *p = head;
    bool newNode = false;

    for(int i=0; s[i]; i++)
    {
        int k = s[i]-0;

        if(p->next[k] == NULL)
        {
            newNode = true;
            p->next[k] = new node();
        }
        p = p->next[k];
    }

    return newNode;
}
void FreeTrie(node *head)
{
    node *p = head;

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

    free(p);
}
int GetMinOrder(char s[], int N)
{///求出来最小表示的首位置
    int i=0, j=1;

    while(i<N && j<N)
    {
        int k=0;

        while(s[i+k] == s[j+k] && k<N)
            k++;

        if(k == N)break;

        if(s[i+k] < s[j+k])
        {
            if(j+k > i)
                j = j+k+1;
            else
                j = i+1;
        }
        else
        {
            if(i+k > j)
                i = i+k+1;
            else
                i = j+1;
        }
    }

    return min(i, j);
}

int main()
{
    int N;

    while(scanf("%d", &N) != EOF)
    {
        char s[MAXN]={0}, p[MAXN];
        node *head = new node();
        int ans = 0, len=0;

        while(N--)
        {
            scanf("%s", p);
            if(!len)len = strlen(p);

            strcpy(s, p);
            strcat(s, p);

            int MinIndex = GetMinOrder(s, len);
            strncpy(p, s+MinIndex, len);///把这个串转换成它的最小表示

            ans += BuildTrie(head, p);
        }

        printf("%d\n", ans);

        FreeTrie(head);
    }

    return 0;
}

 

How many - HDU 2609 (trie+最小表示)

标签:

原文地址:http://www.cnblogs.com/liuxin13/p/4742692.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!