How many HDU - 2609 最小(大)表示法 加 字符串取一部分的函数

问题:

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

题意:给你n个字符串,每个字符串都可以循环(意思是把当前字符串的首字母移到尾字母后面,就这样一直移动),求不同字符串的个数。

思路:用最小表示法或者最大表示法都可以解决,我是用的最小表示法,把每个字符串都表示成最小表示法,然后直接比较就可以啦。思路很简单,这里需要用一个关于字符串的函数,substr()函数,截取字符串的一部分。

substr()函数的用法:设两个字符串必须是string型的即string str1,str2;

str1 = "how are you";// 第一个string字符串对象。
str2=str1.substr(4,3); // 利用substr函数将第一个字符串从str1第 4 位置开始往后数 3 个,所以str2="are"。下标是从0开始的。

如果是string型的两个字符串str1,str2比较大小即直接比较即可str1>str2。

如果是string型的字符串str1复制给str2即直接赋值即可str2=str1。

最小(大)表示法:模板;

int getstr(char s[])
{
    int n=strlen(s);
    int i=0,j=1,k=0,t;//表示从i开始k长度和从j开始k长度的字符串相同
    while(i<n&&j<n&&k<n)
    {
        t=s[(i+k)%n]-s[(j+k)%n];//t用来计算相对应位置上那个字典序较大
        if(!t)k++;//字符相等的情况
        else
        {
            if(t>0) i+=k+1;//i位置大,最大表示法: j += k+1
            else j+=k+1;//j位置大,最大表示法: i += k+1
            if(i==j)j++;
            k=0;
        }
    }
    return min(i,j);
}
//模拟一个字符串就明白了,很简单

本题代码:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<stdlib.h>
#include<iostream>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 1000000007
#define PI acos(-1.0)
#define eps 1e-8
#define N 10005
string s,w[N];
int len,f[N],book[N],flag,n;
int getst()
{
    int i=0,j=1,k=0,t;
    while(i<len&&j<len&&k<len)
    {
        t=s[(i+k)%len]-s[(j+k)%len];
        if(!t) k++;
        else
        {
            if(t>0) i+=k+1;
            else j+=k+1;
            if(i==j)j++;
            k=0;
        }
    }
    return min(i,j);
}
int main()
{
    while(~scanf("%d",&n))
    {
        int k=0;
        for(int i=0; i<n; i++)
        {
            cin>>s;
            len=s.size();
            int getmin=getst();
            flag=0;
            string str;
            str=s.substr(getmin,len-getmin)+s.substr(0,getmin);
            for(int j=0; j<k; j++)
                if(str==w[j]) flag=1;
            if(!flag) w[k++]=str;
        }
        printf("%d\n",k);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值