现在的位置: 首页 > 综合 > 正文

hdu 2609 How many

2013年03月01日 ⁄ 综合 ⁄ 共 1192字 ⁄ 字号 评论关闭

            最小表示法+Trie。首先用最小表示法把所有的串都表示成字典序最小的串,然后把所有的串都放Trie中判断不同串的个数就可以了。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<fstream>
#include<sstream>
#include<cstdlib>
#include<vector>
#include<string>
#include<cstdio>
#include<bitset>
#include<queue>
#include<stack>
#include<cmath>
#include<map>
#include<set>
#define FF(i, a, b) for(int i=a; i<b; i++)
#define FD(i, a, b) for(int i=a; i>=b; i--)
#define REP(i, n) for(int i=0; i<n; i++)
#define CLR(a, b) memset(a, b, sizeof(a))
#define debug puts("**debug**")
#define LL long long
#define PB push_back
#define MP make_pair
using namespace std;
const int N = 1001000;

int chd[N][2], tot;
bool val[N];

int Trie(char *s)
{
    int q = 0;
    for(; *s; s ++)
    {
        int p = *s - '0';
        if(!chd[q][p]) 
        {
            CLR(chd[tot], 0);
            chd[q][p] = tot ++;
        }
        q = chd[q][p];
    }
    if(val[q]) return 0;
    val[q] = true;
    return 1;
}

int Minpri(char *s)
{
    int i = 0, j = 1, k = 0, t, len;
    len = strlen(s);
    while (i < len && j < len && k < len)    
    {
        t = s[(i+k)%len] - s[(j+k)%len];
        if (t == 0) k ++;
        else    
        {    
            if (t > 0) i += k + 1;
            else j += k + 1;
            if (i == j) j ++;
            k = 0;
        }
    }
    return min(i,j);
}

char c[110], cp[110];

int main()
{
    int n, len, ans;
    while(scanf("%d", &n) != EOF)
    {
        ans = 0;tot = 1;
        CLR(val, false);CLR(chd[0], 0);
        for(int i = 0; i < n; i ++)
        {
            scanf("%s", c);
            int t = Minpri(c);
            len = strlen(c);
            for(int j = 0; j < len; j ++)
            {
                cp[j] = c[(j + t) % len];
            }
            cp[len] = '\0';
            ans += Trie(cp);
        }
        printf("%d\n", ans);
    }
}

【上篇】
【下篇】

抱歉!评论已关闭.