标签:贪心 strlen etc getc invalid return turn 分割 while
hihocoder-1327-分割字符串--贪心
给定一个只包含小写字母‘a‘-‘z‘的字符串 S ,你需要将 S 中的字符重新排序,使得任意两个相同的字符不连在一起。
如果有多个重排后字符串满足条件,输出字典序最小的一个。
如果不存在满足条件的字符串,输出INVALID。
字符串S。(1 ≤ |S| ≤ 100000)
输出字典序最小的答案或者INVALID。
aaabc
abaca
使用贪心的方法。本题的分析重点是: 在当前确定使用字典序最小的字符,同时要判断“如果当前使用了这个字符,后面会是合法吗?” 这个问题。
本题的关键点是: 当 cnt[ ch[i] - ‘a‘ ] > (len + 1)/2 时候,就无法组成合法的不相邻字符串,
#include <cstdio> #include <cstring> const int MAXN = 100000 + 10; bool Check(const int a[], const int len, const int b){ for(int i=0; i<len; ++i){ if(a[i] > (b+1)/2){ return false; } } return true; } int main(){ freopen("in.txt", "r", stdin); int len; char ch[MAXN], ans[MAXN]; int cnt[26]; while(scanf("%s", ch) != EOF){ getchar(); len = strlen(ch); memset(cnt, 0, sizeof(cnt)); for(int i=0; i<len; ++i){ ++cnt[ ch[i] - ‘a‘ ]; } bool ans_flag = true; for(int i=0; i<len; ++i){ bool ok = false; for(int j=0; j<26; ++j){ if(cnt[j] > 0 && (i==0 || ans[i-1] != j + ‘a‘ ) ){ --cnt[j]; bool vali = Check(cnt, 26, len-i-1); ok = ok || vali; if(vali){ ans[i] = ‘a‘ + j; break; }else{ ++cnt[j]; } } } if(!ok) { ans_flag = false; break; } } ans[len] = ‘\0‘; if(ans_flag){ printf("%s\n", ans ); }else{ printf("INVALID\n"); } } return 0; }
标签:贪心 strlen etc getc invalid return turn 分割 while
原文地址:http://www.cnblogs.com/zhang-yd/p/7531877.html