三分之一的通过率的字符串
题意为,输入一个S串,有一个空串T。对S串有两种操作,一是取出S串的头放入T串的尾,二是取出S串的尾放入T串的尾。要求是要使得T串的字典序最小。
从题意来看是一个很明显的贪心思路。那么想到这一步其实比较接近答案了,但是需要注意的一点是当S串的头和尾相同的时候,那么这个时候我们当然也希望取出更小的字符,所以就需要比较下一个字符。但是如果指向头和尾的指针都分别往里前进一位的时候,这俩字符还是相同,咋办?这个情形。。。对,就是回文字符串。形同“ABCDCBA”这样的字符串。这个时候是指针不断地往里走,判断为回文字串的时候,两头任意取下一个即可。还有一种情形是类似于这样的串:“ABCCBA”以及“ABCABA”。这些都需要我们把指针不断地移动到中间的时候才能够判断出应该先取哪边的字串才能保证T串的字典序最小。
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <algorithm> 5 using namespace std; 6 const int maxn = 2000+10; 7 char s[maxn]; 8 9 void solve(int n) 10 { 11 int i,l,r,cnt; 12 l = 0; 13 r = n-1; 14 for(cnt=1; l<=r; cnt++) 15 { 16 bool left = false; 17 for(i=0; l+i<=r; i++) 18 { 19 if(s[l+i] < s[r-i]) 20 { 21 left = true; 22 break; 23 } 24 else if(s[l+i] > s[r-i]) 25 { 26 left = false; 27 break; 28 } 29 if((l+i == r-i) && s[l+i] == s[r-i]) 30 { 31 left = true; 32 break; 33 } 34 if((l+i+1 == r-i) && s[l+i] == s[r-i]) 35 { 36 left = true; 37 break; 38 } 39 } 40 //if(top == n-1) left = true; 41 if(left) putchar(s[l++]); 42 else putchar(s[r--]); 43 if(n % 80 != 0) 44 if(cnt % 80 == 0) 45 printf("\n"); 46 } 47 } 48 49 int main() 50 { 51 int n,i; 52 while(scanf("%d%*c",&n) == 1) 53 { 54 char x; 55 memset(s,0,sizeof(s)); 56 for(i=0; i<n; i++) 57 { 58 scanf("%c%*c",&x); 59 s[i] = x; 60 } 61 s[i] = ‘\0‘; 62 solve(n); 63 } 64 return 0; 65 }
时间: 2024-10-26 10:10:26