zoukankan      html  css  js  c++  java
  • hihocoder #1327

    传送门

    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    给定一个只包含小写字母'a'-'z'的字符串 S ,你需要将 S 中的字符重新排序,使得任意两个相同的字符不连在一起。

    如果有多个重排后字符串满足条件,输出字典序最小的一个。

    如果不存在满足条件的字符串,输出INVALID。

    输入

    字符串S。(1 ≤ |S| ≤ 100000)

    输出

    输出字典序最小的答案或者INVALID。

    样例输入
    aaabc
    样例输出
    abaca

    Solution:
    不难看出这题解法是贪心,也不难看出INVALID的充要条件是
    $存在字母i ext{  s.t.  } i在字符串s中出现的次数cnt[i]>lceilfrac{i}{2} ceil.$
    但是容易忽略的一点是:
    如果字符串s是VALID的,不能直接无脑贪心,而要试探:
    $在当前位置放置某字符后,剩下的字符是否还是 ext{VALID}的,如果不是,就不能放置.$
    我在这个点上WA了3发,最后用这个数据
    $ exttt{abcabc}$
    找到了bug.
    我代码输出
    $ exttt{ababc}$
    显然是错的,应当输出
    $ exttt{abacbc}$.

    Implementation:
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int N(1<<17);
     5 
     6 char s[N];
     7 int cnt[26];
     8 
     9 bool valid(int x){
    10     for(int i=0; i<26; i++)
    11         if(cnt[i]>(x-1)/2+1)
    12             return false;
    13     return true;
    14 }
    15 
    16 int main(){
    17     cin>>s;
    18     int n=0;
    19     for(; s[n]; n++)
    20         cnt[s[n]-'a']++;
    21     if(!valid(n)) puts("INVALID");
    22     else{
    23         int pre=-1;
    24         for(int i=0; s[i]; i++){
    25             for(int j=0; j<26; j++)
    26                 if(cnt[j] && j!=pre){
    27                     cnt[j]--;
    28                     if(valid(n-1)){
    29                         putchar('a'+j), pre=j, n--;
    30                         break;
    31                     }
    32                     else cnt[j]++;
    33                 }
    34         }
    35         puts("");
    36     }
    37 }

    conclusion:

    到处都是坑,静态差错查不出时,一定要出几组数据试试,往往能很快找到反例.



  • 相关阅读:
    开始学习C#
    关于串口数据读取的几个问题
    Joel测试
    VC查找内存泄漏技巧【转】
    思考题一
    自我介绍
    2020面向对象程序设计寒假作业1 题解
    思考题二
    题解 洛谷P2158 【[SDOI2008]仪仗队】
    深入浅出InfoPath系列
  • 原文地址:https://www.cnblogs.com/Patt/p/5672220.html
Copyright © 2011-2022 走看看