indeed一道在线笔试题

String Arrangement
Time limit時間制限 : 2sec / Stack limitスタック制限 : 256MB / Memory limitメモリ制限 : 256MB
Problem
  Mr. Takahashi is poor at English. He often mistakes spelling, especially when he spells the words in which same alphabetic character appear successively. For example, he is bad at words such as accept and hellorather than wrong or bye.
  Your task in this problem is to support Mr. Takahashi. You are given a string S that consists only of lower alphabets. Construct a string S’ that satisfies the following conditions.
  For each alphabet, its appearance frequencies in S and S’ are the same.
  Any two adjacent characters in S’ are different.
  If there are more than one string that satisfies these conditions, construct the lexicographically smallest one. If there is no string that satisfies them, report it.
  This problem adopts a special scoring method. If you find it too difficult to construct the lexicographically smallest string, you can earn partial scores by outputting any string that satisfies the two conditions above. Refer to “Note” for more details.
Input
Input is given in the following format;
S
In the first line, string S(1≦|S|≦200000) is given.
Output
Output should be written to the standard output.
Output S’ that satisfies the conditions explained in the description. If such S’ does not exist, output -1. Be sure to print a newline at the end of the output.
Note
There are three sets of inputs in this problem. You can get partial points by solving some of these datasets.
[Dataset 1] All the inputs in this dataset satisfy 1≦|S|≦1000. Moreover, for each input, outputting any string that satisfies the two conditions above is considered correct (regardless of lexicographical order). You will earn 20 points if you solved all the tests in this dataset.
[Dataset 2] All the inputs in this dataset satisfy 1≦|S|≦1000. Only outputting the lexicographically smallest string is considered correct in this dataset. You will earn 20 points if you solved all the tests in this dataset.
[Dataset 3] All the inputs in this dataset satisfy 1≦|S|≦200000. Only outputting the lexicographically smallest string is considered correct in this dataset. You will earn 60 points if you solved all the tests in this dataset.
Input Example1
hello
Output Example1
ehlol
Under the scoring criteria of dataset 1, lheol and olehl are also correct answers.
However, for the scoring criteria of datset 2 and 3, only ehlol is the correct answer.
Input Example2
aaax
Output Example2
-1
We cannot avoid a appearing successively.

题意很简单:
给一个字符串S(长度不超过20w),求S’,
1:S’满足,对于每个字母在S’和S中出现次数相同
2:S’中,相邻的两个字母不能相同

如果有多个S,输出其中字典序最小的

比如:hello,输出:ehlol

如果没有答案输出:-1

我的思路是贪心策略,首先判断一下是否满足,这个只要一个单词出现的次数大于总数 + 1的一半,则肯定不行
然后求字典序最小:
1:预处理,统计每个字母的个数
2:扫一遍,只要没有某个剩余的个数大于总数的一半,就拿和上一次不同的字典序最小的,否则拿超过个数一半的那个

复杂度O(26*N)
因为没有OJ测评,自己测了几个数据,也不知道最后这代码能不能AC

#include <iostream>
#include <string>
#include <algorithm>
int main()
{
#ifdef xxz
    freopen("in.txt","r",stdin);
#endif // xxz
    std::string str;

    while (std::cin >> str) {

        int len = str.length();
        int hash[27] = {0};

        int flag = 0;
        int first = 100;
        for (int i = 0; i < str.length(); i++) {

            hash[str[i] - 'a'] += 1;

            if (str[i] - 'a' < first) {
                first = str[i] - 'a';
            }

            if (hash[str[i] - 'a'] > (len + 1)/2 ) {
                flag = 1;
            }

        }

        if (flag){
            std::cout<<"-1"<<std::endl;

        }
        else{
            std::string ans = "";
            int temp = first;
            int it = first;
            hash[first]--;
            ans.push_back(first + 'a');

            int i,j;
            for (i = len - 1; i >= 1; i--){
                flag = 0;
                it = 27;
                for (j = 0; j < 27; j++) {
                    if (j == temp) continue;
                    if (hash[j] != 0 && j < it) {
                        it = j;
                    }
                    if (hash[j] > i/2) {
                        flag = 1;
                        break;
                    }
                }
                if (flag) {
                    temp = j;
                    ans.push_back(temp + 'a');
                    hash[j]--;
                }
                else {
                    temp = it;
                    ans.push_back(temp + 'a');
                    hash[it]--;

                }
            }
            std::cout<<ans<<std::endl;
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值