1097 拼成最小的数 贪心排序

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1097

2

280

28023

2

280

2802

2

32

323231

首先,起始位比较小的,肯定排在前面的了。然后关键就是如何处理相同的时候,也就是32和321怎么比较。

我的做法:如果比较完后,较短的那个重头开始比较。相当于拼接了上去循环

我想到怎样做的来源是:

它肯定是开头相同的一堆放在一起的,比如开头是1的有n个,肯定是前n个开头都是1的那堆。因为这样结果更优。

那么他们两两比较时,如果有一个没了,那么就由开头的补充,然后wa后,找数据,就这样做了。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;

#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
struct node {
    char str[22];
    int lenstr;
    bool operator < (const struct node & rhs) const {
        int now = 1;
        if (lenstr < rhs.lenstr) {
            for (int i = 1; i <= rhs.lenstr; ++i) {
                if (i > lenstr) {
                    if (str[now] != rhs.str[i]) return str[now] < rhs.str[i];
                    now++;
                    if (now > lenstr) now = 1;
                } else {
                    if (str[i] != rhs.str[i]) return str[i] < rhs.str[i];
                }
            }
            return str[now] < rhs.str[1];
        } else {
            for (int i = 1; i <= lenstr; ++i) {
                if (i > rhs.lenstr) {
                    if (str[i] != rhs.str[now]) return str[i] < rhs.str[now];
                    now++;
                    if (now > rhs.lenstr) now = 1;
                } else {
                    if (str[i] != rhs.str[i]) return str[i] < rhs.str[i];
                }
            }
            return str[1] < rhs.str[now];
        }
        return false;
    }
}a[11111];
const int maxn = 1e6 + 20;
char ans[maxn];
void work() {
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        scanf("%s", a[i].str + 1);
        a[i].lenstr = strlen(a[i].str + 1);
    }
    sort(a + 1, a + 1 + n);
    int lenans = 0;
    for (int i = 1; i <= n; ++i) {
        strcpy(ans + lenans + 1, a[i].str + 1);
        lenans += a[i].lenstr;
    }
    for (int i = 1; i <= lenans; ++i) {
        printf("%c", ans[i]);
        if (i % 1000 == 0) {
            printf("\n");
        }
    }
}

int main() {
#ifdef local
    freopen("data.txt", "r", stdin);
//    freopen("data.txt", "w", stdout);
#endif
    work();
    return 0;
}

时间: 2024-12-28 05:38:09

1097 拼成最小的数 贪心排序的相关文章

51Nod - 1097 拼成最小的数

51Nod - 1097 拼成最小的数 设有n个正整数,将它们联接成一排,组成一个最小的多位整数. 例如: n=2时,2个整数32,321连接成的最小整数为:32132, n=4时,4个整数55,31,312, 33 联接成的最小整数为:312313355 Input 第1行:1个数N.(2 <= N <= 10000) 第2 - N + 1行:每行1个正整数.(1 <= A[i] <= 10^9) Output 输出拼在一起的最小整数.由于数据量太大,请以1000个字符为单位,输

51 nod 1097 拼成最小的数 思路:字符串排序

题目: 思路:1.以字符串输入这些整数. 2.对这些字符串排序,排序规则为尽量让能让结果变小的靠前. 代码中有注释,不懂的欢迎在博客中评论问我. 代码: #include <bits\stdc++.h> using namespace std; string a[10001]; //比较规则:尽量让结果字符串最小 bool cmp(string a,string b){ return a+b <= b+a; } int main(){ int n; cin >> n; for

Min Number 贪心,把最小的数放在最前

题目链接 Problem 2111 Min Number Accept: 499    Submit: 949 Time Limit: 1000 mSec    Memory Limit : 32768 KB Problem Description Now you are given one non-negative integer n in 10-base notation, it will only contain digits ('0'-'9'). You are allowed to c

剑指Offer面试题33(java版):把数组排成最小的数

题目:输入一个正整数数组,把数组里面所有的数字拼接排成一个数,打印能拼接出的所有数字中的一个.例如输入数组{3,32,321},则打印出这3个数字能排成的最小数字321323. 这个题目最直接的做法应该是先求出这个数组中的所有数字的全排列,然后把每个排列拼接起来,最后求出排列起来的数字的最小值.求数组的排列和面试题28非常相似.根据排列组合的只是,n个数字总共有n!排列,我们再来看一下更快的算法. 这道题其实希望我们能够找到一个排序规则,数组根据这个规则排序之后能排成一个最小的数字.要确定排序的

【面试题033】把数组排成最小的数

[面试题033]把数组排成最小的数 题目: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数, 打印能拼接出的所有数字中最小的一个. 例如输入数组{3, 32, 321},则打印出这3个数字能排成的最小数字321323. 思路一: 最直观的想法是求出所有数字的全排列,然后取最小值即可, 根据排列组合的知识,n个数字总共有n!个排列. 思路二: 找到一个排序规则,数组根据这个规则排序之后能排成一个最小的数字. 给出一个规则,判断给出的两个 数字m和n,判断这两个数那个应该排在前面,而不是仅仅

【编程题目】把数组排成最小的数

68.把数组排成最小的数(数组.算法).题目:输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个.例如输入数组{32, 321},则输出这两个能排成的最小数字 32132.请给出解决问题的算法,并证明该算法. 思路:首先,肯定要考虑溢出问题.开始想用字符串,后来改为了用list.思路是先把第一个数字放入list,然后依次把后面的数字插入到合适的位置. 关键问题就是如何判断两个数字哪一个在前面. ①对于 353 .412这样的情况,肯定是第一个数字小的在前面 ②遇到数字

剑指offer (33) 把数组排成最小的数

题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接处的所有数字中最小的一个 例如输入数组 {3, 32, 321}则打印这3个数字能排成的最小数字 321323 两个数字m和n能拼接成数字mn和nm,如果mn < nm,则打印出mn,也就是m排在n之前,我们定义此时 m 小于 n,也就是相当于 自定义了qsort排序的 函数指针 本题拼接数字可能超出表达范围,需用大数解决 int compare(const void* strNumber1, const void* str

2015 湘潭大学程序设计比赛(Internet)Problem D:最小的数

今天的比赛,因为时间问题,我就做了这一个题 题目描述 给你一个n位数,每次操作可以选该数任意的相邻两位进行交换,如果最多可以操作k次,那么最终可以得到的最小的数是什么 (n位且不能含前导零)? 输入 有多组测试数据,第一行为数据个数T(T<=10); 每组数据占一行,包含一个数(不超过1000位)和k(0<=k<=1000),中间用空格隔开; 输出 最终能得到的最小的数. 样例输入 2 321654987 1 321654987 2 样例输出 231654987 132654987 这个

hdu 1518 N根木棒 能否拼成正方形 dfs

N根木棒 能否拼成正方形 Sample Input34 1 1 1 15 10 20 30 40 508 1 7 2 6 4 4 3 5 Sample Outputyesnoyes 1 # include <cstdio> 2 # include <cmath> 3 # include <iostream> 4 # include <cstring> 5 # include <algorithm> 6 using namespace std ;