1 条题解
-
1
我们知道, sort 函数可以选择添加一个 cmp 函数,通过这个规则进行排序,先说结论:
两个字符串 a,b,如果 a+b>b+a 则 a 排在前面。 这个公式的具体意思是当 a 排在 b 前面比 b 排在 a 前面要好,因为字典序更高,所以 a 自然要排在 b 的前面。 例如: 321 和 32 显而易见32132<32321
代码:
#include <bits/stdc++.h> using namespace std; struct num{ string s; }p[100]; bool cmp(num a, num b){ return a.s+b.s>b.s+a.s; //c语言可以模拟组合操作 } int main() { int n; cin>>n; for (int i = 0; i < n; ++i) { cin>>p[i].s; //输入 } sort(p,p+n,cmp); for (int i = 0; i <n ; ++i) { cout<<p[i].s; //输出 } return 0; }
如果不会string可以用写法二的写法来模拟组合
第二种写法和第一种类似 把较短的循环补齐就可以 例如“32”和“323211”则把“32”补齐为“323232” 为什么用循环补齐呢? 因为当两个数前缀相同无论如何组和 都是相同的前缀和剩余的后缀比较 还是这个例子“323211 32”和“32 323211” 我们发现是“11”和“32” 比较。 b+a = 32321132 a+b = 32323211
a = 32 b = 321 a+b = 32321 b+a = 32132 这两个例子很明显看出来对比的地方就是相同的前缀和剩余的比较。所以分别取其中对比的地方你会发现就是将短的字符串循环补齐。 第一个就是 : 323232 323211 进行对比 第二个就是: 323 321 进行对比
#include <bits/stdc++.h> using namespace std; #define int long long #define PII pair<int, int> #define ft first #define se second #define gcd(a,b) __gcd(a,b) #define lcm(a,b) a/gcd(a,b)*b const int inf=1e9; const int mod=80112002; const int N=200005; char jl[10]; struct A { char a[10]; }op[N]; bool cmp(A t,A i) { int lt=strlen(t.a); //t的长度 int li=strlen(i.a);//i的长度 if(lt!=li) { if(li>lt) { for(int q=0;q<li;q++) { jl[q]=t.a[q%lt]; //循环补齐操作 } } else { for(int q=0;q<lt;q++) { jl[q]=i.a[q%lt]; } } } for(int q=0;q<max(lt,li);q++) //循环比较 { if(lt>li) { if(t.a[q]>jl[q]) return t.a>i.a; if(t.a[q]<jl[q]) return t.a<i.a; } if(lt<li) { if(i.a[q]>jl[q]) return i.a>t.a; if(i.a[q]<jl[q]) return i.a<t.a; } if(lt==li) { if(t.a[q]>i.a[q]) return t.a>i.a; if(t.a[q]<i.a[q]) return t.a<i.a; } } return t.a>i.a; } signed main() { int n; cin >>n; for(int q=1;q<=n;q++) { scanf("%s",op[q].a); } sort(op+1,op+1+n,cmp); for(int q=1;q<=n;q++) { printf("%s",op[q].a); } }
- 1
信息
- ID
- 1057
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- 递交数
- 78
- 已通过
- 14
- 上传者