洛谷P1080 [NOIP2012 提高组] 国王游戏

洛谷 P1080

这个国王是真的会玩

这是一道贪心
可以很容易的发现,将左手数字x右手数字大的排后面就是最优解
于是我们就定义一个结构体

struct node{
	int a,b;
	long long c;//表示a*b
}s[MAX];
bool cmp(node x,node y){
	return x.c < y.c;
}

然后一个sort

sort(s+1,s+1+n,cmp);

再模拟一遍
交上去
在这里插入图片描述

这时一看数据范围

对于 100%的数据,有 1 ≤ n ≤ 1,000,0 < a,b < 10000

好吧还要写高精
于是

#include<bits/stdc++.h>
using namespace std;
const int MAX = 1010,MAXN = 1e5;
int n,a,b;
struct node{
	int a,b;
	long long c;
}s[MAX];
bool cmp(node x,node y){
	return x.c < y.c;
}
int len_now,len_maxn,len_sum,maxn[MAXN],now[MAXN],sum[MAXN];
//sum表示前面所有的左手的数的乘积,now表示sum/右手数的商,maxn存答案
inline void cheng(int x){//高精乘低精
	for(int i=1;i<=len_sum;i++) sum[i] *= x;
	for(int i=1;i<=len_sum;i++)
		if(sum[i] >= 10){
			sum[i+1]+=sum[i]/10;
			sum[i]%=10;
			if(i == len_sum) len_sum++;
		}
}
inline void chu(int x){//高精除低精
	int cnt = 0;
	len_now = len_sum;
	for(int i=1;i<=len_now;i++)
		now[i] = sum[i];
	for(int i=len_now;i>=1;i--){
		now[i] += cnt*10;
		cnt = now[i]%x;
		now[i]/=x;
	}
	for(int i=len_now;i>=1;i--)//去除前置0
		if(now[i]) break;
		else len_now--;
}
inline void copy(){//将max更新为now
	len_maxn = len_now;
	for(int i=1;i<=len_now;i++)
		maxn[i] = now[i];
}
inline void work_max(){
	if(len_now > len_maxn){//先比长度
		copy();
		return;
	}
	if(len_now < len_maxn) return;
	for(int i=len_now;i>=1;i--)//逐位比较
		if(now[i] < maxn[i]) return;
		else if(now[i] > maxn[i]){
			copy();
			return;
		}
}
int main(){
	cin >> n >> a >> b;
	for(int i=1;i<=n;i++){
		cin >> s[i].a >> s[i].b;
		s[i].c = s[i].a*s[i].b;
	}
	sort(s+1,s+1+n,cmp);
	len_sum = 1;
	sum[1] = 1;	
	s[0].a = a;//记得乘国王手上的数
	for(int i=1;i<=n;i++){
		cheng(s[i-1].a);
		chu(s[i].b);
		work_max();
	}
	for(int i=len_maxn;i>=1;i--)//倒序输出
		cout << maxn[i];
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值