• 洛谷千题详解 | P1012 [NOIP1998 提高组] 拼数【C++、Java语言】


    博主主页:Yu·仙笙

     

    专栏地址:洛谷千题详解

    目录

    题目描述

    输入格式

    输出格式

    输入输出样例

    解析:

    C++源码:

    C++源码2:

    C++源码3:

    Java源码:


    -------------------------------------------------------------------------------------------------------------------------------  

    -------------------------------------------------------------------------------------------------------------------------------  

    题目描述

    设有 n 个正整数 a1​…an​,将它们联接成一排,相邻数字首尾相接,组成一个最大的整数。

    -------------------------------------------------------------------------------------------------------------------------------  

    输入格式

    第一行有一个整数,表示数字个数 n。

    第二行有 n 个整数,表示给出的 n 个整数ai​。

    -------------------------------------------------------------------------------------------------------------------------------  

    输出格式

    一个正整数,表示最大的整数

    -------------------------------------------------------------------------------------------------------------------------------  

    输入输出样例

    输入 #1复制

    3
    13 312 343
    

    输出 #1复制

    34331213
    

    输入 #2复制

    4
    7 13 4 246

    输出 #2复制

    7424613

    -------------------------------------------------------------------------------------------------------------------------------  

    解析:

    思路分析

    数字收尾相接可以认为是字符串相加,故题意为有 nn 个字符串,s1​,s2​,…sn​,首尾相接形成了一个新字符串,求新字符串字典序最大值。

    做法:

    搜索(部分分) 暴力全排列搜索所有字符串的顺序,比较大小,得出最终答案。

    贪心(满分)

    对贪心正确性的证明:
    分析可见两同样长字符串 s1​,s2​,若s1​ 比s2​ 大,必有 x 使得s1​ 在 x 位第一次比s2​ 大 。

    说明只要前面的位大,就可以忽略后面的位,可以使用贪心解决,把对字典序贡献最大的放在前面。比较方法只要比较s1​+s2​ 和s2​+s1​ 的大小即可。

    如:2 和 19,比较 2 和 19 哪个放在前面使字典序最大,也就是即比较 219 和 192 哪个大,因为 219 比 192 大,所以把 2 放在 19 前面

    使用比较函数 cmp 后 sort 将字符串输出可得答案

    -------------------------------------------------------------------------------------------------------------------------------  

    C++源码:

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. bool cmp(string a,string b){
    6. return a+b>b+a;
    7. }
    8. int main(){
    9. int n;
    10. cin >> n;
    11. string a[n];
    12. for (int i = 0;i> a[i];
    13. sort(a,a+n,cmp);
    14. for (int i = 0;i
    15. cout << a[i];
    16. }
    17. cout << endl;
    18. return 0;
    19. }

    -------------------------------------------------------------------------------------------------------------------------------  

    C++源码2:

    1. #include
    2. using namespace std;
    3. const int N = 25;
    4. string a[N], ans;
    5. bool vis[N];
    6. int n, f;
    7. void dfs(int depth, string now) {
    8. if (depth == n) {
    9. ans = max(ans, now), f = 1;
    10. return;
    11. }
    12. if (f && now < ans && now != ans.substr(0, now.size())) return;
    13. for (int i = 1; i <= n; i ++)
    14. if (!vis[i]) {
    15. vis[i] = true;
    16. dfs(depth + 1, now + a[i]);
    17. vis[i] = false;
    18. }
    19. }
    20. int main() {
    21. cin >> n;
    22. for (int i = 1; i <= n; i ++)
    23. cin >> a[i];
    24. sort(a + 1, a + 1 + n, greater());
    25. dfs(0, "");
    26. cout << ans << '\n';
    27. return 0;
    28. }

    -------------------------------------------------------------------------------------------------------------------------------  

    C++源码3:

    1. #include
    2. #define int long long
    3. using namespace std;
    4. int n,m;
    5. string a, b;
    6. int read(){
    7. int s=0,f=1;
    8. char ch=getchar();
    9. while(ch<'0'||ch>'9'){
    10. if(ch=='-') f=-1;
    11. ch=getchar();
    12. }
    13. while(ch>='0'&&ch<='9'){
    14. s=s*10+ch-'0';
    15. ch=getchar();
    16. }
    17. return s*f;
    18. }
    19. void write(int n){
    20. if(n==0) return;
    21. write(n/10);
    22. putchar(n%10+'0');
    23. }
    24. signed main(){
    25. cin >> a >> b;
    26. cout << a + b;
    27. return 0;
    28. }

    -------------------------------------------------------------------------------------------------------------------------------  

    Java源码

    1. import java.util.Scanner;
    2. public class P1012NOIP1998提高组拼数 {
    3. public static void main(String[] args) {
    4. // TODO Auto-generated method stub
    5. Scanner in=new Scanner(System.in);
    6. int n=in.nextInt();
    7. String s[]=new String[n];
    8. for (int i=0;i
    9. for (int i=0;i
    10. for (int j=i+1;j
    11. /*
    12. * 为解决s[i]=321,s[j]=32时
    13. *32132>32321的情况
    14. */
    15. String s1=s[i]+s[j];
    16. String s2=s[j]+s[i];
    17. if (Integer.parseInt(s2)>Integer.parseInt(s1)) {
    18. String temp=s[i];
    19. s[i]=s[j];
    20. s[j]=temp;
    21. }
    22. }
    23. }
    24. for (int i=0;i
    25. }
    26. }

    -------------------------------------------------------------------------------------------------------------------------------  

  • 相关阅读:
    linux 下vi/vim使用
    VueComponent 笔记
    6_1 系统安全分析与设计
    C++ 【模版进阶】模版分离编译 模版特化
    adb devices unauthorized问题解决
    HarmonyOS应用开发者基础认证【满分答案】
    OpenJDK17-JVM源码阅读-ZGC-并发标记
    【Vue】npm install 命令
    es基础学习笔记问题总结
    菜刀,蚁剑,冰蝎,哥斯拉的流量特征
  • 原文地址:https://blog.csdn.net/djfihhfs/article/details/127706492