vijos1779国王游戏
描述
恰逢H国国庆,国王邀请n位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这n位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。
国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。
格式
输入格式
第一行包含一个整数n,表示大臣的人数。
第二行包含两个整数a和b,之间用一个空格隔开,分别表示国王左手和右手上的整数。接下来n行,每行包含两个整数a和b,之间用一个空格隔开,分别表示每个大臣左手和右手上的整数。
输出格式
输出只有一行,包含一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得的金币数。
输入:
3
1 1
2 3
7 4
4 6
输出:
2
思路:将大臣按左右手整数之积从小到大排序,为解决溢出问题,采用C++大数。
#include <iostream> #include <iomanip> #include <string.h> #include <algorithm> using namespace std; const int MAXN=10005; const int BASE=10000; const int LEN=4; struct BigInt{ int e[MAXN],len; BigInt() { memset(e,0,sizeof(e)); len=0; } void set(int x) { memset(e,0,sizeof(e)); len=0; while(x>0) { e[len++]=x%BASE; x/=BASE; } } bool operator>(const BigInt &b) { if(len>b.len) { return true; } else if(len==b.len) { for(int i=len-1;i>=0;i--) { if(e[i]>b.e[i]) return true; else if(e[i]<b.e[i]) return false; else ; } return false; } else { return false; } } BigInt operator*(const BigInt &b) { BigInt res; for(int i=0;i<len;i++) { int up=0; for(int j=0;j<b.len;j++) { int z=e[i]*b.e[j]+up+res.e[i+j]; res.e[i+j]=z%BASE; up=z/BASE; } if(up!=0) res.e[i+b.len]=up; } res.len=len+b.len; while(res.len>1&&res.e[res.len-1]==0) res.len--; return res; } BigInt operator/(const int &b) { BigInt res=*this; int carry=0; for(int i=len-1;i>=0;i--) { res.e[i]+=carry*BASE; carry=res.e[i]%b; res.e[i]/=b; } while(res.len>1&&res.e[res.len-1]==0) res.len--; return res; } friend ostream &operator<<(ostream &out,const BigInt &b) { out<<b.e[b.len-1]; for(int i=b.len-2;i>=0;i--) { out<<setw(LEN)<<setfill('0')<<b.e[i]; } out<<endl; return out; } }; struct Node{ int x,y; }mon[MAXN]; bool comp(const Node &a,const Node &b) { return a.x*a.y < b.x*b.y; } int n,kl,kr; int main() { cin>>n; cin>>kl>>kr; for(int i=0;i<n;i++) { cin>>mon[i].x>>mon[i].y; } sort(mon,mon+n,comp); BigInt res; res.set(0); BigInt mul; mul.set(kl); for(int i=0;i<n;i++) { BigInt tmp; tmp=mul/mon[i].y; if(tmp>res) res=tmp; BigInt b; b.set(mon[i].x); mul=mul*b; } cout<<res<<endl; return 0; }
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct BigInt{ static const int SIZE = 10000; int e[SIZE], len; BigInt() { len = 0; memset(e, 0, sizeof(e)); } void reset(int x) { while(x > 0) { e[len++] = x % SIZE; x /= SIZE; } while(len > 1 && e[len-1] == 0) len--; } bool operator>(const BigInt& b) { if(len > b.len) return true; else if(len < b.len) return false; else { for(int i = len - 1; i >= 0; i--) { if(e[i] == b.e[i]) continue; else if(e[i] > b.e[i]) return true; else return false; } } return false; } BigInt operator*(const BigInt& b) { BigInt ret; for(int i = 0; i < len; i++) { int up = 0; for(int j = 0; j < b.len; j++) { int z = e[i] * b.e[j] + ret.e[i+j] + up; ret.e[i+j] = z % SIZE; up = z / SIZE; } if(up != 0) { ret.e[i + b.len] = up; } } ret.len = len + b.len; while(ret.len > 1 && ret.e[ret.len-1] == 0) ret.len--; return ret; } BigInt operator/(int b) { BigInt ret = *this; int carry = 0; for(int i = len - 1; i >=0; i--) { ret.e[i] += carry * SIZE; carry = ret.e[i] % b; ret.e[i] /= b; } while(ret.len > 1 && ret.e[ret.len - 1] == 0) ret.len--; return ret; } void print() { printf("%d", e[len-1]); for(int i = len - 2; i >= 0; i--) { printf("%04d", e[i]); } printf("\n"); } }; const int MAXN = 1005; struct Node{ int x, y; }nod[MAXN]; int n, kl, kr; bool comp(Node a, Node b) { return a.x * a.y < b.x * b.y; } int main() { scanf("%d %d %d", &n, &kl, &kr); for(int i = 0; i < n; i++) { scanf("%d %d", &nod[i].x, &nod[i].y); } sort(nod, nod + n, comp); BigInt res, mul; res.reset(kl / nod[0].y); mul.reset(kl); for(int i = 1; i < n; i++) { BigInt b; b.reset(nod[i-1].x); mul = mul * b; BigInt score = mul / nod[i].y; if(score > res) { res = score; } } res.print(); return 0; }