How many HDU - 2609,Glass Beads POJ - 1509 (最小表示法)

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个01字符串表示项链,如果两个01字符串可以通过旋转得到就说这两个串是同一条项链,最后求有多少个不同的项链。

解题思路:用最小表示法轻松解决。。。

最小表示法:

有一个字符串,这个字符串的首尾是连在一起的,要求寻找一个位置,以该位置为起点的字符串的字典序在所有的字符串中中最小。

【暴力算法】:

O(n)的时间枚举起始位置,O(n)的时间比对字符串的字典序,总的时间复杂度是O(n*n)。

【线性算法】:

初始时,让i=0,j=1,k=0,其中i,j,k表示的是以i开头和以j开头的字符串的前k个字符相同

分为三种情况

1.如果str[i+k]==str[j+k] k++。

2.如果str[i+k] > str[j+k] i = i + k + 1,即最小表示不可能以str[i->i+k]开头。

3.如果str[i+k] < str[j+k] j = j + k + 1,即最小表示不可能以str[j->j+k]开头。

那么只要循环n次,就能够判断出字符串的最小表示是以哪个字符开头。

最小表示法模板:

int getMin (){
    int n = strlen(str) ;
    int i = 0, j = 1, k = 0 ;
    while (i < n && j < n && k < n ){
        int tmp = str[(i + k) % n] - str[(j + k) % n] ;
        if (t == 0) k++ ;
        else {
            if (t > 0 ) i += k + 1 ;
            else j += k + 1 ;
            if (i == j) j++ ;
            k = 0 ;
        }
    }
    return i < j ? i : j ;
}

此题解法:可以用vector去存,每次都要去便遍历vector,也可以利用set的无重复性。

/*
@Author: Top_Spirit
@Language: C++
*/
#include <bits/stdc++.h>
using namespace std ;
typedef unsigned long long ull ;
typedef long long ll ;
const int Maxn = 1e5 +10 ;
const ull seed = 133 ;
const int INF = 0x3f3f3f3f ;

string s ;
vector < string > ve ;

int getMin (){
    int len = s.size() ;
    int i = 0, j = 1, k = 0 ;
    while (i < len && j < len && k < len){
        int tmp = s[(i + k) % len] - s[(j + k) % len] ;
        if (!tmp) k++ ;
        else {
            if (tmp > 0) i += k + 1 ;
            else j += k + 1 ;
            if (i == j) j++ ;
            k = 0 ;
        }
    }
    return i < j ? i : j ;
}

int main (){
    int n ;
    while (cin >> n ){
        int ans = 0 ;
        ve.clear() ;
        for (int i = 1; i <= n; i++){
            cin >> s ;
            int len = s.size() ;
            int k = getMin() ;
            string str = s.substr(k, len) + s.substr(0, k) ;
//            cout << str << endl ;
            int Size = ve.size() ;
//            cout << Size <<endl ;
            int flag = 0 ;
            for (int j = 0; j < Size; j++){
                if (ve[j] == str){
                    flag = 1 ;
                    break ;
                }
            }
            if (!flag) ve.push_back(str) ;
        }
        cout << ve.size() << endl ;
    }
    return 0 ;
}
/*
@Author: Top_Spirit
@Language: C++
*/
#include <bits/stdc++.h>
using namespace std ;
typedef unsigned long long ull ;
typedef long long ll ;
const int Maxn = 1e5 +10 ;
const ull seed = 133 ;
const int INF = 0x3f3f3f3f ;

string s ;
set < string > se ;

int getMin (){
    int len = s.size() ;
    int i = 0, j = 1, k = 0 ;
    while (i < len && j < len && k < len){
        int tmp = s[(i + k) % len] - s[(j + k) % len] ;
        if (!tmp) k++ ;
        else {
            if (tmp > 0) i += k + 1 ;
            else j += k + 1 ;
            if (i == j) j++ ;
            k = 0 ;
        }
    }
    return i < j ? i : j ;
}

int main (){
    int n ;
    while (cin >> n ){
        int ans = 0 ;
        se.clear() ;
        for (int i = 1; i <= n; i++){
            cin >> s ;
            int len = s.size() ;
            int k = getMin() ;
            string str = s.substr(k, len) + s.substr(0, k) ;
            se.insert(str) ;
        }
        cout << se.size() << endl ;
    }
    return 0 ;
}

Glass Beads:

Once upon a time there was a famous actress. As you may expect, she played mostly Antique Comedies most of all. All the people loved her. But she was not interested in the crowds. Her big hobby were beads of any kind. Many bead makers were working for her and they manufactured new necklaces and bracelets every day. One day she called her main Inspector of Bead Makers (IBM) and told him she wanted a very long and special necklace. 

The necklace should be made of glass beads of different sizes connected to each other but without any thread running through the beads, so that means the beads can be disconnected at any point. The actress chose the succession of beads she wants to have and the IBM promised to make the necklace. But then he realized a problem. The joint between two neighbouring beads is not very robust so it is possible that the necklace will get torn by its own weight. The situation becomes even worse when the necklace is disjoined. Moreover, the point of disconnection is very important. If there are small beads at the beginning, the possibility of tearing is much higher than if there were large beads. IBM wants to test the robustness of a necklace so he needs a program that will be able to determine the worst possible point of disjoining the beads. 

The description of the necklace is a string A = a1a2 ... am specifying sizes of the particular beads, where the last character am is considered to precede character a1 in circular fashion. 

The disjoint point i is said to be worse than the disjoint point j if and only if the string aiai+1 ... ana1 ... ai-1 is lexicografically smaller than the string ajaj+1 ... ana1 ... aj-1. String a1a2 ... an is lexicografically smaller than the string b1b2 ... bn if and only if there exists an integer i, i <= n, so that aj=bj, for each j, 1 <= j < i and ai < bi

Input

The input consists of N cases. The first line of the input contains only positive integer N. Then follow the cases. Each case consists of exactly one line containing necklace description. Maximal length of each description is 10000 characters. Each bead is represented by a lower-case character of the english alphabet (a--z), where a < b ... z.

Output

For each case, print exactly one line containing only one integer -- number of the bead which is the first at the worst possible disjoining, i.e.\ such i, that the string A[i] is lexicographically smallest among all the n possible disjoinings of a necklace. If there are more than one solution, print the one with the lowest i.

Sample Input

4
helloworld
amandamanda
dontcallmebfu
aaabaaa

Sample Output

10
11
6
5

 

题意: 一串项链由不同大小的珠子连接起来的,但是最小的珠子的地方很容易断裂。让你输出最小珠子的是第几个。

解题思路:用最小表示法求。。

 

/*
@Author: Top_Spirit
@Language: C++
*/
//#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std ;
typedef unsigned long long ull ;
typedef long long ll ;
const int Maxn = 1e5 +10 ;
const ull seed = 133 ;
const int INF = 0x3f3f3f3f ;

string s1 ;

int getMin (string s ){
    int len = s.size() ;
    int i = 0, j = 1, k = 0 ;
    while (i < len && j < len && k < len){
        int tmp = s[(i + k) % len] - s[(j + k) % len] ;
        if (!tmp) k++ ;
        else {
            if (tmp > 0) i += k + 1 ;
            else j += k + 1 ;
            if (i == j) j++ ;
            k = 0 ;
        }
    }
    return i < j ? i : j ;
}

int main (){
    int n ;
    cin >> n ;
    while(n--){
        cin >> s1 ;
        int ans = getMin(s1) ;
        cout << ans + 1 << endl ;
    }
    return 0 ;
}

 

山有木兮卿有意

昨夜星辰恰似你

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值