1 条题解
-
0
C++ :
#include <cstdio> #include <cstring> /* 最少相邻交换变成回文串。 可行性:奇数个数的字符种数 <= (n 为奇数 ? 1 : 0)。 贪心:从两端向中间配对;为左端字符 s[i] 找最靠右的相同字符 k。 · 找到 -> 把它一路交换到右端(记 k..j 的交换数),配对消去; · 没找到 -> s[i] 就是唯一的落单字符,只能往中间挪(代价 n/2 - i), 且只允许出现一次(n 为奇数时)。 */ static char a[8005]; int main(){ int n; if(scanf("%d", &n) != 1) return 0; scanf("%s", a); int cnt[26] = {0}; for(int i = 0; i < n; i++) cnt[a[i] - 'a']++; int odd = 0; for(int i = 0; i < 26; i++) odd += cnt[i] & 1; if(odd > (n & 1)){ printf("Impossible\n"); return 0; } int i = 0, j = n - 1; long long moves = 0; bool used = false; while(i < j){ int k = j; while(k > i && a[k] != a[i]) k--; if(k == i){ if((n % 2 == 0) || used){ printf("Impossible\n"); return 0; } used = true; moves += n / 2 - i; } else { for(int t = k; t < j; t++){ char c = a[t]; a[t] = a[t+1]; a[t+1] = c; moves++; } j--; } i++; } printf("%lld\n", moves); return 0; }
- 1
信息
- ID
- 2822
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- (无)
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者