【NOIP2012 提高组 day1】国王游戏

【NOIP2012 提高组 day1】国王游戏_第1张图片

【NOIP2012 提高组 day1】国王游戏_第2张图片
由公式推导出:
当大臣按照 A*B由小到大排列时,会使得答案取到最小,算出每个人的金币数比较即可
要用高精度乘法和除法,否则只有60分。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=10050,M=4005;
struct node{
	ll x,y;
}a[N];
ll n;
ll sum[M],ans[M],c[M];
ll len1=1,len2=1,len3=1;
ll read(){
	ll sum=0,f=1;
	char ch=getchar();
	while(ch>'9'||ch<'0'){
		 if(ch=='-')f=-1;
		 ch=getchar();
	}
	while(ch<='9'&&ch>='0'){
		 sum=(sum<<3)+(sum<<1)+ch-'0';
		 ch=getchar();
	}
	return sum*f;
}
bool comp(node a,node b){
	return a.x*a.y<b.x*b.y;
}
void cheng(ll x){
   int tmp=0;
   for(int i=1;i<=len1;i++)
   sum[i]*=x;
   for(int i=1;i<=len1;i++)
   {
   	tmp+=sum[i];
   	sum[i]=tmp%10;
   	tmp/=10;
   }
   while(tmp!=0)
   {
   	len1++;
   	sum[len1]=tmp%10;
   	tmp/=10;
   }
}
void chu(ll x){
	memset(ans,0,sizeof(ans));
	len2=len1;
	int tmp=0;
	for(int i=len1;i>=1;i--)
	{
		tmp=(tmp<<3)+(tmp<<1)+sum[i];
		if(tmp>=x){
		   ans[i]=tmp/x;
		   tmp%=x;
	    }
	}
	while(!ans[len2])
	{
		if(len2==1)break;
		len2--;
	}
}
void compare(){
	if(len3>len2)return;
	if(len2>len3){
	    len3=len2;
		for(int i=1;i<=len2;i++)
		c[i]=ans[i];
		return;
	}
	for(int i=len2;i>=1;i--)
	{
        if(c[i]==ans[i])continue;
        if(c[i]>ans[i])return;
        for(int j=1;j<=len2;j++)
        {
		 c[j]=ans[j];
		}
		return;
	}
}
int main(){	
//    freopen("game.in","r",stdin);
//    freopen("game.out","w",stdout);
    sum[1]=1;
	n=read();
    a[0].x=read();
	a[0].y=read();
    for(int i=1;i<=n;i++)
    {
    	a[i].x=read();
    	a[i].y=read();
	}
	sort(a+1,a+n+1,comp);
	
	for(int i=1;i<=n;i++)
	{
	    cheng(a[i-1].x);
		chu(a[i].y);
		compare();		
	}	
	for(int j=len3;j>=1;j--)
    cout<<c[j];
	return 0;
} 

你可能感兴趣的:(NOIP2012提高组)