思路

   遇到可以随便让你排序的题,想最优的排序。(如果很好想就不是关键,+上其他的关键知识,比如dp什么的)

   如果不能谁便看出来,就想前后的关系,满足什么样的条件a才可以到b的前面。

   让后进行排序

   快速排序:

  

代码:

void _qst(int l,int r)
{
    int mid=(r+l)/2;
    int ll=l;
    int rr=r;
    while(l<=r)      <=的目的是为了不让一个点背二分到2个不同地方
                       这层循环是为了让所有的满足此时条件的数互换。
    {
     while(满足在中间点前的条件) l++;
     while(满足在中间点后的条件) r--;
    if(l<=r)         <=同理
    {
        (交换位置)
        l++,r--;       这一步很关键 同理
    }
    }
                      二分继续排
    if(r>ll)
    _qst(ll,r);
    if(l<rr)
    _qst(l,rr);

}

        

  例题

    

国王游戏

 

题目描述

恰逢 HH国国庆,国王邀请n 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 n 位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。

国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。

输入输出格式

输入格式:

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

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

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

输出格式:

一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得的金币数。

输入输出样例

输入样例#1: 
3
1 1
2 3
7 4
4 6 
输出样例#1: 
2

说明

【输入输出样例说明】

1、23 这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;

按 1、3、2 这样排列队伍,获得奖赏最多的大臣所获得金币数为2;

按 21、3 这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;

23、1这样排列队伍,获得奖赏最多的大臣所获得金币数为9

按 31、2这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;

3、2、1 这样排列队伍,获得奖赏最多的大臣所获得金币数为 9。

因此,奖赏最多的大臣最少获得 2个金币,答案输出 2

【数据范围】

对于 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

 

题解:

这道题就比较难想,就思考前后两者之间的关系。

 满足  p[i].a*p[i].b<p[j].a*p[j].b;的情况才能排在j前面。

本题还有高精度*整形的知识点。

坑: 选的那个男人不用乘他左手上的值。

代码:

#include <bits/stdc++.h>
using namespace std;
#define M 1000010
struct _set_ren{
    int a;
    int b;
}p[M];
int ans[M];
int g[M],l=1;
void mul(int k)
{
    for(int i=1;i<=l;i++) g[i]*=k;
    for(int i=1;i<=l;i++)
    {
        g[i+1]+=(g[i]/10);
        g[i]=g[i]%10;
    }
    l++; //
    while(g[l]>9)
    {
        g[l+1]+=(g[l]/10);
        g[l]=g[l]%10;
        l++;
    }
    if(g[l]==0) l--;
}
void _chu(int k)
{
    for(int i=l;i>=1;i--)
    {
        g[i-1]+=((g[i]%k)*10);
        g[i]=g[i]/k;
    }
    while(g[l]==0) l--;
    if(l==0) printf("1"); //
}
void _qst(int l,int r)
{
    int mid=(r+l)/2;
    int ll=l;
    int rr=r;
    while(l<=r)
    {
    while(p[l].a*p[l].b<p[mid].a*p[mid].b) l++;
    while(p[mid].a*p[mid].b<p[r].a*p[r].b) r--;
    if(l<=r)
    {
        int aa=p[l].a,bb=p[l].b;
        p[l].a=p[r].a,p[l].b=p[r].b;
        p[r].a=aa,p[r].b=bb;
        l++,r--; //666666
    }
    }
    if(r>ll)
    _qst(ll,r);
    if(l<rr)
    _qst(l,rr);

}

int n,a,b;
int main(){
    scanf("%d%d%d",&n,&a,&b);
    p[0].a=a;
    p[0].b=b;
    g[1]=a;
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&a,&b);
        p[i].a=a;
        p[i].b=b;
    }
    _qst(1,n);

    for(int i=1;i<n;i++)
    {
        mul(p[i].a);
    }
    _chu(p[n].b);
    for(int i=l;i>=1;i--) printf("%d",g[i]);
}
View Code
02-13 07:45