PAT1038

题目链接:http://pat.zju.edu.cn/contests/pat-a-practise/1038

  基于贪心策略(应该是吧.....):首先按照string类型的比较 从大到小排序,肯定首字母不相同且顺序最大的就应该在最低位,以题给的例子为例 32 321 3214 0229 87 这个数字,排序后从大到小为87 3214 321 32 0229 那么最低位肯定是87了,最主要的问题就是分析如何放置3214 321 32 这几个数字,321是3214的顶头真子串(我自己这样叫的。。), 32又是321 3214的顶头真子串。

  应对策略如下:例如先把87放到位,然后取3214,不是87的顶头真子串,所以放在87之前,接下来取321, 321是3214的顶头真子串,所以接下来问题就是考虑321是放在3214之前还是之后,我是这样考虑的,因为321是3214的顶头真子串,所以放在之前之后影响整个数大小的原因是第321的长度+1位,例如若放在3214之前,第4位(321长度为3嘛)为3, 放在3214之后,第4位为4,所以应该放在3214之前。接下来看32的放置,32是321的顶头真子串,所以基于上述策略分析,32应在321之后,继续,32又是3214的顶头真子串,分析后应该放在3214之后,接下来32与87就没什么好说的了,不是顶头真子串,肯定在之前啦。

  这里说下为什么要非要是真子串,如果有A与B相同了,那么A放在B之前之后,第A.length+1位都是一样的,但是对于后面就不一定了,所以要接着分析其后的,最终确定位置。

  策略就是这样,我用了list容器来放结果,便于插入嘛。 题目最后说前面的最前端的0不要输出,控制下就好。

 1 #include<string>
 2 #include<iostream>
 3 #include<vector>
 4 #include<algorithm>
 5 #include<list>
 6 using namespace std;
 7 
 8 
 9 int main()
10 {
11     int N;
12     while(cin>>N)
13     {
14         vector<string>  v(N);
15         for(int i=0; i<N; ++i)
16             cin>>v[i];
17         sort(v.begin(), v.end());
18         list<string> outcome;
19         /*从大到小取*/
20         for(vector<string>::reverse_iterator riter = v.rbegin(); riter != v.rend(); ++riter)
21         {
22             if(outcome.size()==0)
23                 outcome.push_back(*riter);
24             else
25             {
26                 for(list<string>::iterator iter = outcome.begin(); iter != outcome.end(); ++iter)
27                 {
28                     /*验证是顶头真子串*/
29                     if(iter->find(*riter) == 0 && iter->size() != riter->size())
30                     {
31                         if(iter->at(0) < iter->at(riter->size()))
32                         {
33                             outcome.insert(iter, *riter);
34                             break;
35                         }
36                     }
37                     else
38                     {
39                         outcome.insert(iter, *riter);
40                         break;
41                     }
42                 }
43             }
44         }
45         bool flag(false);
46         for(list<string>::iterator iter=outcome.begin(); iter!=outcome.end(); ++iter)
47         {
48             /*控制前端0不输出*/
49             if(!flag)
50             {
51                 for(int i=0; i<iter->size(); ++i)
52                     if(!flag)
53                     {
54                         if(iter->at(i) != '0')
55                         {
56                             cout<<iter->at(i);
57                             flag=true;
58                         }
59                     }
60                     else
61                         cout<<iter->at(i);
62             }
63             else
64                 cout<<*iter;
65         }
66         /*outcome全是0,那最小就是0*/
67         if(!flag)
68             cout<<0<<endl;
69         else
70             cout<<endl;
71     }
72     return 0;
73 }

 

转载于:https://www.cnblogs.com/bochen-sam/p/3381525.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值