洛谷刷题笔记---P1012 [NOIP1998 提高组] 拼数

C++98 

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
bool cmp(string a,string b){
	return a+b>b+a;
}

int main(){
	int n;
	cin >> n;
	string a[n];
	for (int i = 0;i<n;i++) cin >> a[i];
	sort(a,a+n,cmp);
	for (int i = 0;i<n;i++){
		cout << a[i];
	}
	cout << endl;
	return 0;
}

C++98思路:排序。

python3

def cmp(ra, rb):
    return eval(ra + rb) > eval(rb + ra)
# cmp:保证ra拼接rb是大的
# 也就是保证用前面的元素拼接后面的元素
# 可以使得整体最大

time = int(input())
# time 放置的是多少个数
num = input().split()
# num 存放的那些数字
a = ''
# a 是num排序好后的最后结果
time -= 1
# 只需要 time-1 次大循环即可
while time:
    for i in range(len(num)-1):
        if not cmp(num[i], num[i+1]):
# 如果cmp为0,就需要交换左右元素
# 来确保前拼后整体最大化
            num[i], num[i+1] = num[i+1], num[i]
    time -= 1
            
for i in num:
    a += i
# 将num中的元素一个个拼接到a上
print(a)
# 输出a为最终答案
# print(list(range(time-1)))

python思路:为C++的代码做进一步解释。依旧是排序。

我们每一轮循环都做一件事情:用cmp比较相邻元素,如果cmp(相邻元素)==0,那么就要交换相邻元素的位置,来保证用前面的元素拼接后面的元素后,整体的数字是最大化的。

但是为什么要做time-1次大循环呢?

首先,我们这个问题的本质无疑是给各个数字寻找正确的位置,又有time个数字,那每个数字只需要跟time-1个元素进行cmp函数后,就可以找到正确的位置。而一轮循环可以给一个数字找到正确的位置,那么size-1次循环就可以给size个数字找到正确的位置(因为最后一个不用排)。

那为什么保证相邻元素满足cmp函数就可以保证数字整体最大化呢?

如果a+b是比b+a大的,那么我们给a拼接个c,就变成了a+c。那么a+c+b是不是一定会比b+a+c大呢?举个例子:a=2,b=1,c=3。a+b=21,b+a=12,显然前者是大于后者的,那么a+c+b=231,b+a+c=123,是不是又是前者比后者大?无论是a+c还是c+a,结果都是如此。

为什么这题会做不出来呢?

首先,是对字符串拼接的遗忘,忘记了C++中还可以通过“+”来拼接,故而思路向数学方向走了。

其次,是不清楚C++中string字符串的数字比较机制:"123">"231"==false。

以为char*类的字符串不能正确的进行数字比较:"213">"123"==false,就认为string也不行。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HUTAC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值