POJ 3617 贪心

题目链接: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 }

贪心就是找到一个子问题的最优解,然后扩展到全局,进而找到全局最优解。多练多想

posted on 2015-05-05 01:03  Bei_insomia  阅读(268)  评论(2编辑  收藏  举报

导航