【题解】NOIP2012-S-DAY1-2-国王游戏

题目描述

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

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

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

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

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

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

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

输入格式

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

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

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

和右手上的整数。

输出格式

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

金币数。

输入样例

3 1 1 2 3 7 4 4 6

输出样例

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。

数据范围

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

时间限制:

1S

空间限制:

128M


不难想到,本题可通过交换相邻两个人后对结果的影响来找出最终答案(即相邻交换法)——这就如同冒泡排序一般。

当然,这个题想起来简单,但重要的是证明!!!

设前 i-1 个人总乘积为 x ,则交换前后 i,i+1 两人的价值变化如下:

交换前: v_i=\frac{x}{b_i} ①

v_{i+1}=\frac{a_ix}{b_{i+1}} ②

交换后: v_i=\frac{x}{b_{i+1}} ③

v_{i+1}=\frac{a_{i+1}x}{b_i} ④

max(①,②)\leq max(③,④) (即后者价值更高),则交换;否则不交换。

max(①,②)\leq max(③,④) ​移项通分得:

max(\frac{x}{b_i},\frac{a_{i+1}x}{b_{i+1}})\leq max(\frac{x}{b_{i+1}},\frac{a_ix}{b_i})\\ \iff max(\frac{1}{b_i},\frac{a_i}{b_{i+1}})\leq max(\frac{1}{b_{i+1}},\frac{a_{i+1}}{b_i})——两边同除以x\\ \iff max(b_{i+1},a_{i}b_i)\leq max(b_i,b_{i+1}a_{i+1})——两边同时乘b_ib_{i+1}\\

现证明:将整个序列按 a_ib_i\leq a_{i+1}b_{i+1} ​排序与上述情况相同,

\because所有数字\geq 1\\ \therefore b_{i+1}\leq a_{i+1}b_{i+1}\\ \therefore max(b_{i+1},a_{i}b_i)\leq max(b_i,b_{i+1}a_{i+1})\\ \iff((b_{i+1}\leq b_i)或(b_{i+1}\leq a_{i+1}b_{i+1}))且((a_ib_i\leq b_i)或(a_ib_i\leq a_{i+1}b_{i+1}))\\ \iff(a_ib_i\leq b_i)或(a_ib_i\leq a_{i+1}b_{i+1})\\ \iff (a_i=1)或 (a_ib_i\leq a_{i+1}b_{i+1})\\ 当a_i=1时:\\ max(b_{i+1},a_{i}b_i)\leq max(b_i,b_{i+1}a_{i+1})\\ \iff max(b_{i+1},b_i)\leq max(b_i,b_{i+1})——显然这是成立的\\ \therefore max(b_{i+1},a_{i}b_i)\leq max(b_i,b_{i+1}a_{i+1})与a_ib_i\leq a_{i+1}b_{i+1}等价

所以将整个序列用 a_ib_i 从小到大排序即可。


当你快快乐乐写完代码:

#include <bits/stdc++.h>
using namespace std;
struct node{
    long long left_hand_num,right_hand_num,sort_num;
}wmy[10005];
bool cmp(node a,node b){
    return a.sort_num<b.sort_num;
}
int main()
{
    long long ans=-1;
    long long n;
    scanf("%lld",&n);
    long long x,y;
    scanf("%lld%lld",&x,&y);
    for(int i=1;i<=n;i++){
        scanf("%lld%lld",&wmy[i].left_hand_num,&wmy[i].right_hand_num);
        wmy[i].sort_num=wmy[i].left_hand_num*wmy[i].right_hand_num;
    }
    sort(wmy+1,wmy+n+1,cmp);
    for(int i=1;i<=n;i++){
    	ans=max(ans,x/wmy[i].right_hand_num);
        x*=wmy[i].left_hand_num;
    }
    printf("%lld",ans);
    return 0;
}

结果WA60——为什么呢?

!!!!高精度!!!!

2 个赞

格式炸了,谁帮我修一下TAT

2 个赞

好了,现在修好了

2 个赞

世纪之花问题

题目描述

“丛林变得焦躁不安…” 世纪之花的触手正在向丛林的各个角落蔓延。现在丛林中已经有 x 个触手,每过一分钟世纪之花会长出一些新触手,新触手的数量等于当前触手数的最小质因子。勇者想知道,再经过几分钟,触手数量就不小于 y 了呢?

输入格式

第一行包含一个整数 T,表示数据组数。

接下来 T 行,每行两个正整数 x 和 y。

输出格式

输出 T 行,每行一个整数表示答案。

样例输入

4
2 23
9 20
5 100
6 89

样例输出

11
5
46
42

数据规模

  • 1 ≤ T ≤ 1000
  • 2 ≤ X ≤ 10
  • 20 ≤ Y ≤ 10^9

解决思路

通过交换相邻两个人后对结果的影响来找出最终答案(即相邻交换法)——这就如同冒泡排序一般。设前 ( i-1 ) 个人总乘积为 ( x ),则交换前后 ( i,i+1 ) 两人的价值变化如下:

  • 交换前:
    [
    v_i = \frac{a_i x}{b_i} \quad \text{①}
    ]
    [
    v_{i+1} = \frac{a_{i+1} a_i x}{b_{i+1}} \quad \text{②}
    ]

  • 交换后:
    [
    v_i = \frac{a_{i+1} x}{b_{i+1}} \quad \text{③}
    ]
    [
    v_{i+1} = \frac{a_i a_{i+1} x}{b_i} \quad \text{④}
    ]

若 ( \max(\text{①, ②}) \leq \max(\text{③, ④}) ),则交换;否则不交换。

将 ( \max(\text{①, ②}) \leq \max(\text{③, ④}) ) 移项通分得:
[ \max(b_{i+1}, a_i b_i) \leq \max(b_i, b_{i+1} a_{i+1}) ]

证明:将整个序列按 ( a_i b_i \leq a_{i+1} b_{i+1} ) 排序与上述情况相同。

证明步骤

因为所有数字都不小于1:
[ b_{i+1} \leq a_{i+1} b_{i+1} ]
[ \max(b_{i+1}, a_i b_i) \leq \max(b_i, b_{i+1} a_{i+1}) ]

当 ( a_i = 1 ) 时:
[ \max(b_{i+1}, a_i b_i) \leq \max(b_i, b_{i+1} a_{i+1}) ]
[ \max(b_{i+1}, b_i) \leq \max(b_i, b_{i+1}) ] 这显然成立

因此 ( \max(b_{i+1}, a_i b_i) \leq \max(b_i, b_{i+1} a_{i+1}) ) 与 ( a_i b_i \leq a_{i+1} b_{i+1} ) 等价。

所以将整个序列用 ( a_i b_i ) 从小到大排序即可。

我整理的格式也炸了

3 个赞

前后打$时空格空开

3 个赞