题目链接:http://poj.org/problem?id=3617
大致题意:给定一个字符串s,通过这个字符串来构造一个新的字符串t,从s的头部或者尾部删除一个小的字符加入t的尾部。
分析,我们很容易想到,直接判断头尾大小即可。可是,这样的话,如果头尾相等的话,那么对于哪一个先删去还是无法确定。这个时候我们就需要比较相等字符的前一个字符,如果还相等,那么继续比较。。知道找到那个不等的字符,找到即跳出循环。
这段代码很精细。却不是我写的。
代码如下:
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 using namespace std; 5 6 int main() 7 { 8 char s[2005]; 9 int n,i,j,k; 10 scanf("%d",&n); 11 for(i=0;i<n;i++) 12 { 13 char ch; 14 cin>>ch; 15 s[i]=ch; 16 }//注意输入的时候用cin比较方便,因为是单个字符输入,如果用sacnf的话,换行什么的用getchar来吸收也是有效的,可是程序一直报错。。。。= =|| 17 int num=0; 18 int a=0,b=n-1;//设置头尾两个地址。。 19 while (a<=b) 20 { 21 bool l=false;//用l标记删除头字符还是尾字符。 22 for(i=0;a+i<=b;i++)//如果s[a+i]==s[b-i] 依次循环,找到不等的那一个字符,跳出循环。这就是这个算法的精辟之处。 23 { 24 if(s[a+i]<s[b-i])//如果找到的不等的那个字符是前面小于后面的。。则删除前面的。。先把s[a]输出,然后再把地址a++ 25 { 26 l=true; 27 break; 28 }else if(s[a+i]>s[b-i])//如果不等的那个字符是后面小于前面,则删除后面的,先把s[b]输出,再把地址b--; 29 { 30 l=false; 31 break; 32 }//如果s[a+0]==s[b-0],即无法判断出,则直接i++,那么继续判断s[a+1]与s[b-1]大小,循环往复,知道找到不等的情况。 33 } 34 if(l) 35 printf("%c",s[a++]);//先输出s[a],后a++ 36 else 37 printf("%c",s[b--]);//先输出s[b],后b--; 38 num++; 39 if(num%80==0)//题目还有一个细节处理,输出的字符每一行不得超过80个字符。意味着当字符个数num是80的倍数时,换行依次。 40 printf("\n"); 41 } 42 printf("\n"); 43 return 0; 44 }
贪心就是找到一个子问题的最优解,然后扩展到全局,进而找到全局最优解。多练多想
时间: 2024-10-16 15:04:56