[贪心][字符串] Jzoj P3207 Orthogonal Anagram
题解
- 我们可以预处理出每个字母出现的次数l[i]和没有出现的次数r[i]
- 若一个字母出现的次数>没有出现的次数,那么显然这个是没有方案的,因为要满足每一位的字母都不一样,这样的话,就超过n/2个了,显然不能形成
- 现在来想一下如何用预处理出来的数组来求答案
- 考虑贪心的思想,要使字典序最小,那么可以放的最小的字母可以先放
- 那么就枚举放的字母,若l[i]=r[i],也就是说,它占整个字符串的一半,而且我们是按顺序枚举过来的,显然可以放
- 若没有以上的情况,那么我们就找第一个不等于字符串相对位置,而且是出现过的字母放就好了
代码
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 int l[26],r[26],n; 5 char s[50010]; 6 int main() 7 { 8 scanf("%s",s+1),n=strlen(s+1); 9 for (int i=1;i<=n;i++) for (int j=0;j<26;j++) if (s[i]==j+97) l[j]++; else r[j]++; 10 for (int i=0;i<26;i++) if (l[i]>r[i]) return 0; 11 for (int i=1;i<=n;i++) 12 { 13 int x=26; 14 for (int j=0;j<26;j++) if (s[i]!=(j+97)&&l[j]==r[j]) x=j; 15 if (x==26) for (int j=0;j<26;j++) if (s[i]!=(j+97)&&l[j]) {x=j; break;} 16 printf("%c",x+97),l[x]--; 17 for (int j=0;j<26;j++) if (s[i]!=(j+97)) --r[j]; 18 } 19 }