易位构词EOJ3451【字符串】【思维题】【模拟】
http://acm.ecnu.edu.cn/problem/3451/
我们可以先考虑字符串有序的情况,比如是 aaabcc
,我们只要将字符串右移 3 位,变成 bccaaa
,就做完了。那么对于无序的情况,我们可以通过排序让它有序,做完之后再排回去。
显然最多的字母出现次数大于一半的情况是不行的。否则就将每个字母的位置和字母绑定一下,按字母序对结构体进行排序。然后右移「出现最多的字母出现次数」位,再排回来就可以了。
当时没想到这是模拟,看题解不知道如果是无序的排完序后怎样弄回去。。。。
其实结构体记录数组的下标id是不变的!!!做完再排回去就是排id啊啊啊啊!
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 const int maxn=1e5+100; 8 9 struct Ch 10 { 11 char c; 12 int id; 13 }; 14 Ch c[maxn]; 15 int total[30]; 16 17 bool cmp1(const Ch&A,const Ch&B) 18 { 19 if(A.c==B.c) return A.id<B.id; 20 return A.c<B.c; 21 } 22 23 bool cmp2(const Ch&A,const Ch&B) 24 { 25 return A.id<B.id; 26 } 27 28 int main() 29 { 30 char s[maxn]; 31 while(scanf("%s",s)==1) 32 { 33 memset(total,0,sizeof(total)); 34 int len=strlen(s); 35 int m=0; 36 for(int i=0; i<len; i++) 37 { 38 c[i].c=s[i]; 39 c[i].id=i; 40 total[s[i]-'a']++; 41 m=max(m,total[s[i]-'a']); 42 } 43 if(m>len/2) 44 { 45 printf("impossible\n"); 46 } 47 else 48 { 49 sort(c,c+len,cmp1); 50 char tmp[maxn]; 51 for(int i=0; i<len; i++) tmp[i]=c[i].c; 52 for(int i=0; i<len; i++) 53 { 54 c[i].c=i-m>=0?tmp[i-m]:tmp[i+len-m]; 55 } 56 sort(c,c+len,cmp2); 57 for(int i=0; i<len; i++) printf("%c",c[i].c); 58 printf("\n"); 59 } 60 } 61 return 0; 62 }