• 国王游戏


    Description
    恰逢H国国庆,国王邀请n位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右

    手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这n位大臣排

    成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每

    位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右

    手上的数,然后向下取整得到的结果。

    国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,

    使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。

    Input
    输入文件为game.in

    第一行包含一个整数n,表示大臣的人数。

    第二行包含两个整数a和b,之间用一个空格隔开,分别表示国王左手和右手上的整数。

    接下来n行,每行包含两个整数a和b,之间用一个空格隔开,分别表示每个大臣左手

    和右手上的整数。

    Output
    输出文件名为game.out。

    输出只有一行,包含一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得的

    金币数。

    Sample Input
    3
    1 1
    2 3
    7 4
    4 6

    Sample Output
    2
    【输入输出样例说明】
    按1、2、3号大臣这样排列队伍,获得奖赏最多的大臣所获得金币数为2;
    按1、3、2这样排列队伍,获得奖赏最多的大臣所获得金币数为2;
    按2、1、3这样排列队伍,获得奖赏最多的大臣所获得金币数为2;
    按2、3、1这样排列队伍,获得奖赏最多的大臣所获得金币数为9;
    按3、1、2这样排列队伍,获得奖赏最多的大臣所获得金币数为2;
    按3、2、1这样排列队伍,获得奖赏最多的大臣所获得金币数为9。
    因此,奖赏最多的大臣最少获得2个金币,答案输出2。

    Data Constraint

    Hint
    对于20%的数据,有1≤ n≤ 10,0 < a、b < 8;
    对于40%的数据,有1≤ n≤20,0 < a、b < 8;
    对于60%的数据,有1≤ n≤100;
    对于60%的数据,保证答案不超过10^9;
    对于100%的数据,有1 ≤ n ≤1,000,0 < a、b < 10000。

    .
    .
    .
    .
    .
    .
    分析
    设紧挨着的两个人a,b的左右手数字分别为La,Lb,Ra,Rb,设a和b前面的所有人的左手的数字的乘积为S,可以发现,交换ab的顺序不会影响ab前面所有人得到的金币数,也不会影响ab后面所有人得到的金币数目,那么可以假设让a排在b前面比让b排在a前面的结果更优:

    a在b前时:
    a获得的金币数为:S/Ra ———– #1
    b获得的金币数为:SLa/Rb ———–#2
    b在a前时:
    a获得的金币数为:S
    Lb/Ra ———–#3
    b获得的金币数为:S/Rb ————#4

    那么要想让假设成立,就必须有:max(#1 , #2) < max(#3 , #4)———#5
    很明显可以看出,#1 < #3 ,# < #4
    如果要#5成立,还必须有#3 > #2 ,即 SLb/Ra > SLa/Rb
    化简得到:LbRb > LaRa
    所以得到左右手数字乘积小的排在前面会使得结果更优。

    最后,要用高精计算。

    .
    .
    .
    .
    .
    程序:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int a[20000],b[20000],w[20000],d[20000],maxx[100000],len,f,maxxlen,a1[100000],a2[100000];
    char str[100000];
    
    void kp(int l,int r)
    {
    	if (l>r) return;
    	int i=l,j=r,mid=w[(l+r)/2];
    	do 
    	{
    		while (w[i]<mid) i++;
    		while (w[j]>mid) j--;
    		if (i<=j)
    		{
    			a[0]=a[i];a[i]=a[j];a[j]=a[0];
    			b[0]=b[i];b[i]=b[j];b[j]=b[0];
    			w[0]=w[i];w[i]=w[j];w[j]=w[0];
    			i++;j--;
    		}
    	}while (i<=j);
    	kp(l,j);
    	kp(i,r);
    }
    
    
    void cheng(int a[],int b)
    {
        memset(d,0,sizeof(d));
        for(int i=1;i<=len;i++) 
    		d[i]=a[i]*b;
        for (int i=1;i<=len;i++)
            if (d[i]/10)
    		{
                d[i+1]+=d[i]/10;
                d[i]%=10;
            }
        while (d[len+1]) len++;
        while (d[len]/10)
    	{
            d[len+1]+=d[len]/10;
            d[len]%=10;
            len++;
        }
        for (int i=1;i<=len;i++) 
    		a[i]=d[i];
    }
    
    void chu(int a[],int b)
    {
        memset(d,0,sizeof(d)); 
        int x=0;
        for(int i=1;i<=len;i++)
        {
            d[i]=(a[i]+x*10)/b;
            x=(a[i]+x*10)%b;
        }
        int pd=0;
        for (int i=1;i<=len;i++)
    	if (d[i]!=0)
    	{
            pd=1;
    		break;
        }
        if (pd!=0)
        {
            int i=1;
            while (d[i]==0) i++;
            f=i;
            while (i<=len)
    		{
                if (d[i]>maxx[i]&&len-f+1==maxxlen||len-f+1>maxxlen)
    			{
                    for (int j=f;j<=len;j++) 
    					maxx[j]=d[j];
                    maxxlen=len-f+1;
                    break;
                }
                if (maxxlen>len-f+1||d[i]<maxx[i]) break;
                i++;
            }
        }
    }
    
    int main()
    {
    	int n,aa,bb;
    	scanf("%d",&n);
    	scanf("%d%d",&aa,&bb);
    	for (int i=1;i<=n;i++)
    	{
    		scanf("%d%d",&a[i],&b[i]);
    		w[i]=a[i]*b[i];
    	}
    	kp(1,n);
    	int i=0;
        while (aa!=0)
    	{
            str[i]=aa%10+'0';
            aa/=10;
            i++;
        }
        len=strlen(str);
        for (int i=1;i<=len;i++) 
    		a1[i]=str[i-1]-'0';
        for (int i=1;i<=len;i++) 
    		a2[i]=str[len-i]-'0';
        for (int i=1;i<=n;i++)
        {
            chu(a2,b[i]);
            cheng(a1,a[i]);
            for (int j=1;j<=len;j++) 
    			a2[j]=a1[len-j+1];
        }
        for (int i=f;i<=maxxlen+f-1;i++) 
    		cout<<maxx[i];
    	return 0;
    }
    
  • 相关阅读:
    在ubuntu下关闭笔记本触摸板
    (转载)实用小命令 windows下查看端口占用情况
    (转载)JBoss 4.2.3下部署EJB 3.0碰到的local和remote问题
    Windows下通过xmanager远程桌面控制Linux(转)
    SQL Server 事务日志的问题
    回归
    用友软件工程IT应用研究院
    关于Oracle数据库的死锁(转书摘)
    关于企业级Web2.0的一点想法
    关注Java的开源项目(中文版)
  • 原文地址:https://www.cnblogs.com/YYC-0304/p/10292780.html
Copyright © 2020-2023  润新知