TIANKENG’s restaurant(Ⅱ) - hdu4886

                              TIANKENG’s restaurant(Ⅱ)

                     Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 130107/65536 K (Java/Others)
                     Total Submission(s): 882    Accepted Submission(s): 317


 

Problem Description

After improving the marketing strategy, TIANKENG has made a fortune and he is going to step into the status of TuHao. Nevertheless, TIANKENG wants his restaurant to go international, so he decides to name his restaurant in English. For the lack of English skills, TIANKENG turns to CC, an English expert, to help him think of a property name. CC is a algorithm lover other than English, so he gives a long string S to TIANKENG. The string S only contains eight kinds of letters-------‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’, ‘H’. TIANKENG wants his restaurant’s name to be out of ordinary, so the restaurant’s name is a string T which should satisfy the following conditions: The string T should be as short as possible, if there are more than one strings which have the same shortest length, you should choose the string which has the minimum lexicographic order. Could you help TIANKENG get the name as soon as possible?

Meanwhile, T is different from all the substrings of S. Could you help TIANKENG get the name as soon as possible?

Input

The first line input file contains an integer T(T<=50) indicating the number of case.
In each test case:
Input a string S. the length of S is not large than 1000000.

Output

For each test case:
Output the string t satisfying the condition.(T also only contains eight kinds of letters-------‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’, ‘H’.)

Sample Input
 

3 
ABCDEFGH
AAABAACADAEAFAGAH 
ACAC

Sample Output
 

AA 
BB 
B

Source

BestCoder Round #2

Recommend

liuyiding

题目大意:

给一个只含A-H八种字母的字符串s,输出字符串t,字符串t与s的任意子串都不相等,且也仅含A-H,且t是满足上述条件的字符串中长度最小,字典序最小的字符串。

题目分析:

题目说字符串长度不超过1e6, 长度为6的字符串有8^{6}大约26万中,比6小的字符串一定是长度为6的字符串的子串,假如这些字符串不共用首尾,那么要出现在一个字符串中大约要6 * 26万的长度,显然t串长度不会超过7,事实上,长度为6足够了。由于下面我使用8进制进行hash(怕9进制会太大,并且会使vis使用变得很麻烦,因为我们要跳过那些不可能的hash值下标,而且vis数组也需要时间清零,我们不必浪费空间),为了区分A与AA等类似的情况(因为hash完都是0),我们先对长度进行枚举,枚举长度1到6,注意下面代码虽然len是从0到5,但是第二层循环是len + i < s.size(),而不是len + i - 1 < s.size(),然后vis数组找到没被标记的hash值,我们就可以得到答案了,答案字符串的存储可以使用string类,因为我使用字符数组超时了,不知道为什么。

代码:

#include <iostream>
#include <cstdio>
#include <string>
#include <cmath>
#include <cstring>
using namespace std;
const int N = 3e6;
int vis[N];
string s;
int main()
{
    ios :: sync_with_stdio(false);
    int t;
    cin >> t;
    while(t --){
        string ans;
        cin >> s;
        int h;
        int f = 0;
        for (int len = 0; len < 6; len ++){
            memset(vis, 0, sizeof(vis));
            for (int i = 0; i < s.size() - len; i ++){
                h = 0;
                for (int j = i; j <= i + len; j ++){
                    h = h * 8 + s[j] - 'A';
                }
                vis[h] = 1;
            }
            int k = pow(8, len + 1);
            int p = 0;
            for (int i = 0; i < k; i ++){
                if(!vis[i]){
                    h = i;
                    while(h > 0){
                        ans = (char)(h % 8 + 'A') + ans;
                        p ++;
                        h /= 8;
                    }
                    while(p <= len){
                        ans = 'A' + ans;
                        p ++;
                    }
                    cout << ans << endl;
                    f = 1;
                    break;
                }
            }
            if (f == 1)break;
        }
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值