Erase Numbers II
已经提交 已经通过
10.38%
Total Submission:1204
Total Accepted:125
题目描述
给定 nn 个正整数 a_1, a_2, \cdots, a_na1,a2,⋯,an,它们组成了序列 AA。
你的任务是删除其中 (n - 2)数字,使得 A中剩余的数字连起来的所表示的数字最大,并给出这个值。
严格来讲,如果剩余数字在 A 中的下标为 p_1, p_2, \cdots, p_mp1,p2,⋯,pm (1 \leq p_1 < p_2 < \cdots < p_m \leq n1≤p1<p2<⋯<pm≤n),则它们连起来所表示的数字为 \overline{a_{p_1} a_{p_2} \cdots a_{p_m}}ap1ap2⋯apm。
输入描述
输入包含多组测试数据。第一行包含一个整数 TT,表示测试数据的组数。随后的内容是各组测试数据。对于每组测试数据:
第一行包含一个整数 nn。
第二行包含 nn 个整数 a_1, a_2, \cdots, a_na1,a2,⋯,an,保证每个数字不含前导零。
- 1 \leq T \leq 30001≤T≤3000
- 2 \leq n \leq 60002≤n≤6000
- 1 \leq a_i \leq 10^91≤ai≤109
- 所有测试数据的 nn 之和不超过 60006000。
输出描述
对于每组测试数据,输出一行Case #x: y
(不含引号),其中x
是测试数据的编号(从 11 开始编号),y
是这组数据的答案。
样例输入 1
3
3
6 6 6
4
21 12 12 21
2
998244353 985661441
样例输出 1
Case #1: 66 Case #2: 2121 Case #3: 998244353985661441
思路:把n个数字简化成三个数字(这里用字符串)的处理;即:
a b c
f1=a+b
f2=a+c
f3=b+c
求最优的两个数字相接。
记录最优的两个数字,加入第三个数字。重复上面的操作。
复杂度为O(n)
很奇怪.....这题很简单也很快....将解题的时候感觉没提过这种方法(讲的是O(n²)的方法)
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <map>
using namespace std;
typedef long long LL;
const int maxn=10000;
int cmp(string s1,string s2)
{
int l1=s1.size();
int l2=s2.size();
if(l1>l2)return 1;
else if(l1<l2)return 0;
if(s1>s2)return 1;
else return 0;
}
int main()
{
int t;
scanf("%d",&t);
int cnt=1;
while(t--)
{
int n;
string a[maxn];
scanf("%d",&n);
for(int i=0;i<n;i++)
{
cin>>a[i];
}
string l=a[0],r=a[1];
string f1,f2,f3;
for(int i=2;i<n;i++)
{
f1=l+r;
f2=l+a[i];
f3=r+a[i];
if(cmp(f1,f2)&&cmp(f1,f3)){
l=l,r=r;
}
else if(cmp(f2,f1)&&cmp(f2,f3))
{
l=l;r=a[i];
}
else if(cmp(f3,f1)&&cmp(f3,f2)){
l=r;r=a[i];
}
//cout<<l<<" "<<r<<endl;
}
string ans=l+r;
printf("Case #%d: ",cnt++);
cout<<ans<<endl;
}
}