[最小表示法] hdu 2609 How many

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=2609

How many

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 1225    Accepted Submission(s): 476

Problem Description

Give you n ( n < 10000) necklaces ,the length of necklace will not large than 100,tell me

How many kinds of necklaces total have.(if two necklaces can equal by rotating ,we say the two necklaces are some).

For example 0110 express a necklace, you can rotate it. 0110 -> 1100 -> 1001 -> 0011->0110.

Input

The input contains multiple test cases.

Each test case include: first one integers n. (2<=n<=10000)

Next n lines follow. Each line has a equal length character string. (string only include ‘0‘,‘1‘).

Output

For each test case output a integer , how many different necklaces.

Sample Input

4
0110
1100
1001
0011
4
1010
0101
1000
0001

Sample Output

1
2

Author

yifenfei

Source

奋斗的年代

Recommend

yifenfei   |   We have carefully selected several similar problems for you:  1131 2572 1251 2610 2603

Statistic | Submit | Discuss | Note

题目意思:

给n个有0,1组成的串,求可以经过循环旋转,最后不同的串有多少个。

解题思路:

最小表示法。

先求出每个串的字典序最小的串,存入map里,最后输出map大小即可,也可以存入字典树,最后输出叶子个数。

代码:

//#include<CSpreadSheet.h>

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#include<cmath>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

#define Maxn 220

map<string,int>myp;
char save[Maxn];
int n;

string cal()
{
    int len=strlen(save);

    int i=0,j=1;

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

        while(k<len&&save[(i+k)%len]==save[(j+k)%len])
            k++;
        if(k>=len)
            break;
        if(save[(i+k)%len]>save[(j+k)%len])
        {
            i=i+k+1;
            if(i==j)
                i++;
        }
        else
        {
            j=j+k+1;
            if(i==j)
                j++;
        }
        //printf("i:%d j:%d k:%d\n",i,j,k);
        //system("pause");

    }
    int tt=min(i,j);

    int cnt=0;
    string res;

    while(cnt<len)
    {
        res+=save[(tt+cnt)%len];
        cnt++;
    }
    return res;

}

int main()
{
   //freopen("in.txt","r",stdin);
   //freopen("out.txt","w",stdout);
   while(~scanf("%d",&n))
   {
       myp.clear();

       while(n--)
       {
           scanf("%s",save);
           string a=cal();
           //cout<<": "<<a<<endl;
           //system("pause");
           myp[a]=1;
       }
       printf("%d\n",myp.size());
   }
   return 0;
}

[最小表示法] hdu 2609 How many

时间: 2024-10-21 10:07:57

[最小表示法] hdu 2609 How many的相关文章

hdu 2609 How many 最小表示法

How many Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1248    Accepted Submission(s): 486 Problem Description Give you n ( n < 10000) necklaces ,the length of necklace will not large than 100

HDU 2609 最小表示法

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2609 题意:给定n个循环链[串],问有多少个本质不同的链[串](如果一个循环链可以通过找一个起点使得和其他串相同,那么就认为这2个链是一样的.就是求不同构的串) 思路:对于求同构串可以用最小表示法,然后判断是否相等就可以知道这2个是否是同构了.判重用的是set #define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<cstdi

HDU 2609 How many (最大最小表示法)

How many Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2184    Accepted Submission(s): 904 Problem Description Give you n ( n < 10000) necklaces ,the length of necklace will not large than 100

hdu 2609 How many (最小表示法)

题意 给 \(n\) 个循环串,求本质不同串的数量 传送门 思路 最小表示法求下标,从最小下标处作为串的起点,将新串放到map中去重,最终map中的元素数量即为最终答案. 最小/大表示法 Code #include <cstdio> #include <cstring> #include <map> #include <string> using namespace std; const int maxn = 1e6+10; int n, l; char s

HDU 4162 Shape Number(字符串,最小表示法)

HDU 4162 题意: 给一个数字串(length <= 300,000),数字由0~7构成,求出一阶差分码,然后输出与该差分码循环同构的最小字典序差分码. 思路: 第一步是将差分码求出:s[i] = (s[i] - s[i+1] + 8) % 8; 第二步是求出最小字典序的循环同构差分码,我之前没注意到字符串规模..直接用set做,MLE+TLE... 正确的方式应该是一种O(n)的解法,即最小表示法.//关于最小表示法的证明与详述请参考最小表示法:) 最小表示法算法: 初始时,i=0,j=

Hdu 5442 Favorite Donut (2015 ACM/ICPC Asia Regional Changchun Online 最大最小表示法 + KMP)

题目链接: Hdu 5442 Favorite Donut 题目描述: 给出一个文本串,找出顺时针或者逆时针循环旋转后,字典序最大的那个字符串,字典序最大的字符串如果有多个,就输出下标最小的那个,如果顺时针和逆时针的起始下标相同,则输出顺时针. 解题思路: 看到题目感觉后缀数组可以搞,正准备犯傻被队友拦下了,听队友解释一番,果断丢锅给队友.赛后试了一下后缀数组果然麻烦的不要不要的(QWQ),还是最大最小表示法 + KMP来的干净利索. 最大表示法:对于一个长度为len文本串,经过循环旋转得到长度

String Problem hdu 3374 最小表示法加KMP的next数组

String Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1492    Accepted Submission(s): 662 Problem Description Give you a string with length N, you can generate N strings by left shifts.

hdu 3374 String Problem (kmp+最大最小表示法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题目大意:输出最大和最小的是从哪一位开始的,同时输出最小循环节的个数. 这里简单介绍对字符串最小表示的方法: (1)  利用两个指针p1, p2.初始化时p1指向s[0], p2指向s[1]. (2)  k = 0开始,检验s[p1+k] 与 s[p2+k] 对应的字符是否相等,如果相等则k++,一直下去,直到找到第一个不同,(若k试了一个字符串的长度也没找到不同,则那个位置就是最小表示位置,

hdu String Problem(最小表示法入门题)

hdu 3374 String Problem 最小表示法 view code#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <string> using namespace std; const int N = 10010; int n; char s[105]; map<