洛谷P1012 [NOIP1998 提高组] 拼数 C语言/C++

Posted 灬人生如梦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷P1012 [NOIP1998 提高组] 拼数 C语言/C++相关的知识,希望对你有一定的参考价值。

[NOIP1998 提高组] 拼数

题目描述

设有 n n n 个正整数 a 1 … a n a_1 \\dots a_n a1an,将它们联接成一排,相邻数字首尾相接,组成一个最大的整数。

输入格式

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

第二行有 n n n 个整数,表示给出的 n n n 个整数 a i a_i ai

输出格式

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

样例 #1

样例输入 #1

3
13 312 343

样例输出 #1

34331213

样例 #2

样例输入 #2

4
7 13 4 246

样例输出 #2

7424613

提示

对于全部的测试点,保证 1 ≤ n ≤ 20 1 \\leq n \\leq 20 1n20 1 ≤ a i ≤ 1 0 9 1 \\leq a_i \\leq 10^9 1ai109

所需变量

int n;//代表n个整数

int arr[22][15] = 0;//将每个数的每位都取出来

int i;//循环变量

int control;//代表每个数的位数

int sum[22];//用于存储每个数

我们优先要思考两个数怎么判断谁放在前面,谁放在后面!当然是最大位谁更大就放谁,代码如下:

for(int k = 1;k<=n;k++)
   max = 0;
   for(i = 0;i<n;i++)
       if(arr[i][0] == 0)
           continue;
       
       if(arr[i][arr[i][0]]>arr[max][arr[max][0]])
           max = i;
       else if(arr[i][arr[i][0]] == arr[max][arr[max][0]])
           if(solution(i,max) == 0)
               if(judge(i,max) == 0)
                   max = i;
               
           else if(solution(i,max) == 1)
               max = i;
           
       
   

对于如果首位相等的情况下,我们就判断他后面的位数大小,代码如下(谁后面的位数更大,就优先选谁):

int solution(int a,int b)
    int x,y;
    x = arr[a][0];
    y = arr[b][0];
    while(x != 0||y != 0)
        if(arr[a][x] == arr[b][y])
            
        else if(arr[a][x] > arr[b][y])
            return 1;
        else if(arr[a][x] < arr[b][y])
            return 2;
        
        --x;--y;
    
    return 0;

如果两个数用solution函数还是判断不出来我们就进入judge函数判断,就是当所有位都相等的情况下,我们就判断随便一个数的首位和更长的那个数的下一位(没有被匹配的那一位),谁更大就选择谁:

int judge(int a,int b)
    int x = arr[a][0];
    int y = arr[b][0];
    if(x==y)
        return 1;
    else if(x>y)
        for(int u = 0;u<n;u++)
            if(arr[u][0] == 0)
                continue;
            else
                if(arr[u][arr[u][0]]>arr[a][y-x])
                    return 1;
                
            
        
        return 0;
    else
        for(int u = 0;u<n;u++)
            if(arr[u][0] == 0)
                continue;
            else
                if(arr[u][arr[u][0]]>arr[b][y-x])
                    return 0;
                
            
        
        return 1;
    

将上面所需模块都实现的情况下,按照正常顺序拼凑起来就得到下面的完整代码(编译器是dev,语言是C语言):

#include<iostream>
using namespace std;
int n,arr[22][15] = 0,i,control,sum[22];
int solution(int a,int b)
    int x,y;
    x = arr[a][0];
    y = arr[b][0];
    while(x != 0||y != 0)
        if(arr[a][x] == arr[b][y])
            
        else if(arr[a][x] > arr[b][y])
            return 1;
        else if(arr[a][x] < arr[b][y])
            return 2;
        
        --x;--y;
    
    return 0;

int judge(int a,int b)
    int x = arr[a][0];
    int y = arr[b][0];
    if(x==y)
        return 1;
    else if(x>y)
        for(int u = 0;u<n;u++)
            if(arr[u][0] == 0)
                continue;
            else
                if(arr[u][arr[u][0]]>arr[a][y-x])
                    return 1;
                
            
        
        return 0;
    else
        for(int u = 0;u<n;u++)
            if(arr[u][0] == 0)
                continue;
            else
                if(arr[u][arr[u][0]]>arr[b][y-x])
                    return 0;
                
            
        
        return 1;
    

int main()
    int max;
    cin>>n;
    for(i = 0;i<n;i++)
        cin>>sum[i];
        control = 1;
        int temp = sum[i];
        while(temp>0)
            arr[i][control++] = temp%10;
            temp = temp/10;
        
        arr[i][0] = --control;
    
    for(int k = 1;k<=n;k++)
        max = 0;
        for(i = 0;i<n;i++)
            if(arr[i][0] == 0)
                continue;
            
            if(arr[i][arr[i][0]]>arr[max][arr[max][0]])
                max = i;
            else if(arr[i][arr[i][0]] == arr[max][arr[max][0]])
                if(solution(i,max) == 0)
                    if(judge(i,max) == 0)
                        max = i;
                    
                else if(solution(i,max) == 1)
                    max = i;
                
            
        
        cout<<sum[max];
        arr[max][0] = 0;
    
    return 0;

洛谷-拼数-NOIP1998提高组复赛

题目描述 Description

设有n个正整数(n≤20),将它们联接成一排,组成一个最大的多位整数。
例如:n=3时,3个整数13,312,343联接成的最大整数为:34331213
又如:n=4时,4个整数7,13,4,246联接成的最大整数为:7424613
 输入输出格式 Input/output
输入格式:
第一行,一个正整数n。
第二行,n个正整数。
输出格式:
一个正整数,表示最大的整数
 输入输出样例 Sample input/output
样例测试点#1

输入样例:

3
13
131
343

输出样例:

34313131

说明 description

30%的数据, n≤l0,每个数<10^3。 50%的数据, n≤l00。 100%的数据, n≤1000,每个数<10^200。

 

思路:这题乍一看,wow,还蛮简单的哦。我当时的思路是:把这些数按顺序每个排一遍,比较一下大小,但这种方法实在很慢,几十个就爆了。

但可以仔细观察下一下规律:要使一个数更大,首先要使首位尽量的大,并且要使一个数的位数尽量的大!

太棒了,这就是正确的思路,怎么实现呢?这时,很快联想到,诶,这不是字符串的比较方法吗?!太棒了,就用字符串来解决!

这题就演变成了简单的字符串二维数组排序,太棒了!

代码如下:

 1 #include <stdio.h>
 2 #include <string.h>
 3 void sort(char array[][1001],int n)//排序函数
 4 {
 5     char temp[202];
 6     int i,j,k;
 7     for(i=0;i<n-1;i++)
 8     {
 9         k=i;
10         for(j=i+1;j<n;j++)
11             if(strcmp(array[k],array[j])<0)//大到小排序 
12             k=j;
13         if(k!=i)
14         {
15             strcpy(temp,array[i]);   //字符串交换顺序
16             strcpy(array[i],array[k]);
17             strcpy(array[k],temp);
18         }
19     }
20 }
21 int main()
22 {
23     int n,i;
24     char str[1001][1001];
25     scanf("%d",&n);
26     for(i=0;i<n;i++)
27     {
28         scanf("%s",str[i]);//输入N个字符串
29     }
30     sort(str,n);//对输入的字符串排序
31     for(i=0;i<n;i++)
32     {
33         printf("%s",str[i]);
34     }
35     printf("\n"); 
36     return 0;
37 }

 

以上是关于洛谷P1012 [NOIP1998 提高组] 拼数 C语言/C++的主要内容,如果未能解决你的问题,请参考以下文章

洛谷P1012 [NOIP1998 提高组] 拼数 C语言/C++

P1012 [NOIP1998 提高组] 拼数

洛谷 P1012 拼数

洛谷-拼数-NOIP1998提高组复赛

[NOIP1998]拼数

洛谷——P1012 拼数