(Luogu) P1080 国王游戏 (贪心)

传送门

解题思路:一开始单纯的直接按照左手升序或者右手降序,这种想法必然是不准确的,但是能得30分,那么应该如何判断哪些大臣应该被排在前面呢,现在我们不如直接从所有的大臣种先选出两位来判断。

属性 左手 右手
皇上 X1 Y1
大臣甲 X2 Y2
大臣乙 X3 Y3

 

如果是这样的话,那答案就是有两种排序方式max(X1/Y2,X1*X2/Y3),max(X1/Y3,X1*X3/Y2) 取个最小值即为答案。

k1=X1/Y2,k2=X1*X2/Y3

k3=X1/Y3,k4=X1*X3/Y2, 首先可以很容易的判断出   k4>k1, k2>k3的;现在假设第一种排序方式更好,即最大值最小,那就只需要k2<k4就行了,那第一种排序的两个都比第二种小了。化简一下就是X2*Y2<X3*Y3;

但是有序左右相乘乘出来的数非常大,用unsigned long long 也只有60分。

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
int n;
struct node {
	ull a,b,c;
} t[1010];
ull s,ans;
bool cmp(node a,node b) {
	return a.c<b.c;
}
int main() {
	std::ios::sync_with_stdio(false);
	cin>>n;
	for(int i=0; i<=n; i++) {
		cin>>t[i].a>>t[i].b,t[i].c=t[i].a*t[i].b;
	}
	sort(t+1,t+1+n,cmp);
	s=t[0].a;
	for(int i=1; i<=n; i++) {
		ans=max(ans,s/t[i].b),s*=t[i].a;
	}
	cout<<ans;
}

高精度不想写了,咕咕咕。

#include<cstdio>
#include<cstring>
#include<algorithm>
const int maxn = 1005;
struct Nodes {
	int l, r;
	bool operator < (const Nodes &rhs) const {
		return l * r < rhs.l * rhs.r;
	}
} s[maxn];
int n;
int L, R;
struct INT {
	int a[10005], len;
	INT() {
		memset(a, 0, sizeof a);
		len = 0;
	}
	void init(int x) {
		if(x == 0) len = 1;
		else {
			while(x) {
				a[len++] = x % 10;
				x /= 10;
			}
		}
	}
	bool operator < (const INT &rhs) const {
		if(len != rhs.len) return len < rhs.len;
		for(int i = len - 1; i >= 0; i--) {
			if(a[i] < rhs.a[i]) return true;
			else if(a[i] > rhs.a[i]) return false;
		}
		return false;
	}
	INT operator * (const int &rhs) const {
		INT ret;
		for(int i = 0; i < len; i++) ret.a[i] = a[i] * rhs;
		int llen;
		for(int i = 0; i < len || ret.a[i]; i++) {
			if(ret.a[i] / 10) {
				ret.a[i + 1] += ret.a[i] / 10;
				ret.a[i] %= 10;
			}
			llen = i;
		}
		if(ret.a[llen] == 0) ret.len = llen;
		else ret.len = llen + 1;
		return ret;
	}
	INT operator / (const int &x) const {
		INT ret;
		ret.len = len;
		int rest = 0;
		for(int i = len - 1; i >= 0; i--) {
			rest = rest * 10 + a[i];
			ret.a[i] = rest / x;
			rest %= x;
		}
		while(ret.len > 1 && ret.a[ret.len - 1] == 0) ret.len--;
		return ret;
	}
	void print() {
		for(int i = len - 1; i >= 0; i--) printf("%d", a[i]);
		printf("\n");
	}
};
int main() {

	scanf("%d%d%d", &n, &L, &R);
	for(int i = 1; i <= n; i++) scanf("%d%d", &s[i].l, &s[i].r);
	std::sort(s + 1, s + n + 1);
	INT temp;
	temp.init(L);
	INT ans;
	for(int i = 1; i <= n; i++) {
		ans = std::max(ans, temp / s[i].r);
		temp = temp * s[i].l;
	}
	ans.print();
	return 0;

}

猜你喜欢

转载自blog.csdn.net/TDD_Master/article/details/85222405