标签:贪心 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