设有n个正整数,将他们连接成一排,组成一个最大的多位整数。
如:n=3时,3个整数13,312,343,连成的最大整数为34331213。
如:n=4时,4个整数7,13,4,246连接成的最大整数为7424613。
有多组测试样例,每组测试样例包含两行,第一行为一个整数N(N<=100),第二行包含N个数(每个数不超过1000,空格分开)。
每组数据输出一个表示最大的整数。
2 12 123 4 7 13 4 246
12312 7424613
#include <iostream> #include <algorithm> using namespace std; bool campare(string i ,string j){ return (i+j)>(j+i); } int main(){ int n; while(cin>>n){ vector<string>temp(n,""); for(int i = 0 ; i < n ; ++i){ cin>>temp[i]; } sort(temp.begin(),temp.end(),campare); for(int i = 0 ; i < n;++i) cout<<temp[i]; cout<<endl; } return 0; }
看到大家都使用了Collections类,我说一下我的解法(除了scanner,没有import任何东西)。
首先,本题可以理解为对N个数进行排序,只不过排序的标准不是数值的大小,而是两个字符串组合到一起转化成整形后的数值大小,所以只需要随便采用一种排序方法,在比较大小时改成比较字符串组合的大小就行。
话不多说,上代码:
import java.util.Scanner;
/**
* Created by kevin on 17-9-5.
* Mail: chewenkaich@gmail.com
*/
public class Main {
public static void main(String[] args) {
// 获取输入
Scanner in = new Scanner(System.in);
int count = Integer.valueOf(in.nextLine().trim());
if (count > 100) return;
String inStr = in.nextLine().trim();
String[] dataStr = inStr.split(" ");
int[] data = new int[dataStr.length];
for (int i = 0; i < dataStr.length; i++) {
data[i] = Integer.valueOf(dataStr[i]);
}
// 此处为一个冒泡排序,也可以使用其他快排,归并等其他高效排序方法
for (int pass = data.length - 1; pass >= 0; pass--) {
for (int i = 0; i < pass; i++) {
if (!is1stBiggerThan2nd(data[i], data[i + 1])) { // 第i个数“小于”第i+1个数
int tem = data[i + 1];
data[i + 1] = data[i];
data[i] = tem;
}
}
}
// 输出结果
String result = "";
for (int each : data) {
result += String.valueOf(each);
}
System.out.println(result);
}
/**
* 从两个整数组合起来较大时,其中的第一个整数,例如,
* a=3489, b=3423
* 因为a组合b = 34893423 > b组合a = 34233489,所以返回a
*
* @param a
* @param b
* @return true, a+b > b+a; false, a+b < b+a
*/
static boolean is1stBiggerThan2nd(Integer a, Integer b) {
if (Integer.valueOf(String.valueOf(a) + String.valueOf(b)) > Integer.valueOf(String.valueOf(b) + String.valueOf(a)))
return true;
else return false;
}
}
最终程序运行结果如下
运行时间:169ms
占用内存:13040k
如果有任何问题,欢迎指正。
import java.util.*; /** * * @author 何嘉龙 * */ public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); while (in.hasNext()) { int n = in.nextInt(); List<Integer> list = new ArrayList<>(); for (int i = 0; i < n; i++) { list.add(in.nextInt()); } Collections.sort(list, new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { String s1 = String.valueOf(o1); String s2 = String.valueOf(o2); return (s2 + s1).compareTo(s1 + s2); } }); for (int i = 0; i < list.size(); i++) { System.out.print(list.get(i)); } System.out.println(); } } }
//其实这就是个字符串的冒泡排序,如果字符串A+B>B+A那么认为A>B //以此为准则,采用冒泡排序的方法将字符串按大小排序,然后输出就可以了 #include<stdio.h> #include<stdlib.h> #include<string.h> int main() { int i,j; int num=0; char data[100][5]={'\0'}; char tempa[7]={'\0'},tempb[7]={'\0'},temp[5]={'\0'}; scanf("%d",&num); for(i=0;i<num;i++) { scanf("%s",data[i]); } strcpy(temp,data[0]); for(i=0;i<num;i++) { for(j=i+1;j<num;j++) { strcpy(tempa,data[i]); strcat(tempa,data[j]); strcpy(tempb,data[j]); strcat(tempb,data[i]); if(strcmp(tempa,tempb)<0) { strcpy(temp,data[j]); strcpy(data[j],data[i]); strcpy(data[i],temp); } } printf("%s",data[i]); } system("pause"); return 0; }
bool cmp(const string &a, const string &b) { string l = a, r = b; int i=0; //如果两个字符串长度不同,则将另一个字符穿的前缀补到尾部 if(l.size() < r.size()) while(l.size() < r.size()) l += r[i++]; else while (l.size() > r.size()) r += l[i++]; //降序排列 return l >= r; } int main() { int N; while (cin >> N) { vector<string> num(N); for (int i = 0; i<N; ++i) cin >> num[i]; sort(num.begin(), num.end(), cmp); for (auto c : num) cout<<c; cout << endl; } }
自己写cmp函数 即将两个数前后位置不同的两种情况比较
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
vector<string> ve;
int cmp(string a, string b){
long x = atol((a + b).c_str());
long y = atol((b + a).c_str());
if(x < y) return 1;
return 0;
}
int main(){
int n;
while(scanf("%d", &n) == 1){
ve.clear();
string s;
for(int i = 0; i < n; i++){
cin>>s;
ve.push_back(s);
}
sort(ve.begin(), ve.end(), cmp);
for(int i=ve.size()-1;i>=0;i--) cout<<ve[i];
cout<<endl;
}
}
#include <stdio.h> #include <iostream> #include <string.h> #include <stdlib.h> const int N = 100; const int MaxLen = 3; char num1[MaxLen+1]; char num2[MaxLen+1]; char buf1[2*MaxLen+1]; char buf2[2*MaxLen+1]; int myCompare(const void* n1, const void* n2) { sprintf(num1, "%d", *(int*)n1); sprintf(num2, "%d", *(int*)n2); strcpy(buf1, num1); strcat(buf1, num2); strcpy(buf2, num2); strcat(buf2, num1); return strcmp(buf1, buf2); } int main() { int n = 0; int buf[N]; while (std::cin >> n) { for (int i = 0; i < n; ++i) { std::cin >> buf[i]; } qsort(buf, n, sizeof(int), myCompare); for (int i = n-1; i >= 0; --i) { std::cout << buf[i]; } std::cout << "\n"; } }
分享一个很好理解的冒泡算法,python3.5,因为我自己不会用cmp,所以就用了这个笨一点的办法
N = int(input())
nums = list(map(str,input().split()))
for i in range(len(nums)):
for j in range(1,len(nums)-i):
if nums[j-1]+nums[j] < nums[j]+nums[j-1]:
nums[j-1],nums[j] = nums[j],nums[j-1]
res = int("".join(nums))
print(res)
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()){
int n = in.nextInt();
ArrayList<Integer> als = new ArrayList<Integer>();
for (int i = 0; i < n; i++) {
als.add(in.nextInt());
}
als.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
String a = String.valueOf(o1);
String b = String.valueOf(o2);
return (b + a).compareTo(a + b);
}
});
for (Integer i:
als) {
System.out.print(i);
}
System.out.println();
}
}
}
//一句话:字符串的冒泡排序;和数组的排序区别在于:以前是比较前后数字大小,现在比较前后数字,不同顺序合并后 //的大小 import java.util.*; class Solusion{ public void sort_num(String []str){ int n = str.length; if(n <= 1) System.out.print(str[0]); else { String temp; for(int i = 0; i < n; i ++){ for(int j = 0; j < n - i -1; j ++){ if( Integer.valueOf( str[j] + str[j + 1] ) > Integer.valueOf( str[j + 1] + str[j] ) ){ temp = str[j]; str[j] = str[j + 1]; str[j + 1] = temp; } } } for(int i = n - 1; i >= 0;i --) System.out.print(str[i]); System.out.println(); } } } public class Main{ public static void main(String []args){ Scanner sc = new Scanner(System.in); while(sc.hasNext()){ int n = sc.nextInt(); String []str1 = new String[n]; for(int i = 0 ; i < n ;i ++) str1[i] = sc.next(); Solusion solusion = new Solusion(); solusion.sort_num(str1); } } }
#include "bits/stdc++.h" using namespace std; const int MAXN=100+5; int num[MAXN]; bool cmp(int a,int b) { char x[]="111111",y[]="111111"; sprintf(x,"%d%d",a,b); sprintf(y,"%d%d",b,a); if(strcmp(x,y)>0) return true; return false; } int main() { int N=0; while(cin>>N) { for(int i=0;i<N;i++) cin>>num[i]; sort(num,num+N,cmp);//特殊排序 for(int i=0;i<N;i++) cout<<num[i]; cout<<endl; } return 0; }
using namespace std;
int main()
{
int m = 0;
cin >> m;
vector<int> n(m);//存取每个数字
vector<int> o(m,1);//存取每个数字的位数
vector<int> f(m, 0);//存取每个数字的首位数
for (auto &a : n)
{
cin >> a;
}
int b = 0;
for (int i = 0; i < m; i++)
{
b = n[i];
if (b < 10)
{
f[i] = b;
}
while (b >= 10)
{
b = b / 10;
f[i] = b;
o[i]++;
}
}
int p = 0;
for (int u = 0; u < m; u++)
{
for (int i = 0; i < m - u - 1; i++)
{
if (n[i] * pow(10, o[i + 1]) + n[i + 1]>n[i + 1] * pow(10, o[i]) + n[i])//判断相邻两位拼接的顺序
{
p = f[i];
f[i] = f[i + 1];
f[i + 1] = p;
p = o[i];
o[i] = o[i + 1];
o[i + 1] = p;
p = n[i];
n[i] = n[i + 1];
n[i + 1] = p;
}
}
}
for (int i = m - 1; i >= 0; i--)
{
cout << n[i];
}
cout << endl;
return 0;
}
运行时间:4ms
占用内存:480k
import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNextInt()) { int n = sc.nextInt(); List<String> list = new ArrayList<>(); while (n-- != 0) list.add(sc.next()); Collections.sort(list, (str1, str2) -> (str2 + str1).compareTo(str1 + str2)); for (String s : list) System.out.print(s); System.out.println(); } sc.close(); } }