HDU-4442-Physical Examination (2012年金华赛区现场赛A题)

Physical Examination

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 5915    Accepted Submission(s): 1656

Problem Description

WANGPENG is a freshman. He is requested to have a physical examination when entering the university.

Now WANGPENG arrives at the hospital. Er….. There are so many students, and the number is increasing!

There are many examination subjects to do, and there is a queue for every subject. The queues are getting longer as time goes by. Choosing the queue to stand is always a problem. Please help WANGPENG to determine an exam sequence, so that he can finish all
the physical examination subjects as early as possible.

Input

There are several test cases. Each test case starts with a positive integer n in a line, meaning the number of subjects(queues).

Then n lines follow. The i-th line has a pair of integers (ai, bi) to describe the i-th queue:

1. If WANGPENG follows this queue at time 0, WANGPENG has to wait for ai seconds to finish this subject.

2. As the queue is getting longer, the waiting time will increase bi seconds every second while WANGPENG is not in the queue.

The input ends with n = 0.

For all test cases, 0<n≤100000, 0≤ai,bi<231.

Output

For each test case, output one line with an integer: the earliest time (counted by seconds) that WANGPENG can finish all exam subjects. Since WANGPENG is always confused by years, just print the seconds mod 365×24×60×60.

Sample Input

5
1 2
2 3
3 4
4 5
5 6
0

Sample Output

1419

Hint

In the Sample Input, WANGPENG just follow the given order. He spends 1 second in the first queue, 5 seconds in the 2th queue, 27 seconds in the 3th queue,
169 seconds in the 4th queue, and 1217 seconds in the 5th queue. So the total time is 1419s. WANGPENG has computed all possible orders in his
120-core-parallel head, and decided that this is the optimal choice.

Source

2012 Asia JinHua Regional Contest

由简单至复杂,先讨论2个的情况:

a1 b1

a2 b2

如果现有的顺序是最佳顺序,那么一定有关系:

a1 + a1*b2 + a2 <= a2 + a2*b1 + a1

等价于     a1*b2 < a2*b1

那么之后的都按照a1*b2 < a2*b1 来排序!

AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int mo=365*24*60*60;
const int maxn=100010;

struct fun
{
	__int64 a,b;
}node[maxn];

bool cmp(fun a, fun b)
{
	return a.a*b.b<b.a*a.b;
}

int main()
{
	int n, i, j;
	while(scanf("%d", &n), n)
	{
		for(i = 0; i<n; i++)
		{
			scanf("%I64d %I64d", &node[i].a, &node[i].b);
		}
		sort(node, node+n, cmp);
		__int64 ans = 0, tem = 0;
		for(i = 0; i<n; i++)
		{
			ans+=(node[i].a+tem*node[i].b)%mo;
			ans%=mo;
			tem = ans;
		}
		printf("%I64d\n", ans);
	}
	return 0;
}  

其实我还看了看别人的代码(感觉我的代码逻辑不对劲,但是过了):

a1 b1

a2 b2

如果现有的顺序是最佳顺序,那么一定有关系:

a1 + a1*b2 + a2 <= a2 + a2*b1 + a1

还可以等价于 a1/b1 < a2/b2

这样使得a1和b1在一块了,a2和b2在一块了,对于往后退可以更方便。

比如三组:

a1  b1

a2  b2

a3  b3

可以得到   a1/b1  <  a2/b2   <   a3/b3

以此类推,也可以按照这样排序!

代码(别人的代码,没提交过。。):

#include<iostream>
#include<cstdlib>
#include<vector>
#include<map>
#include<cstring>
#include<set>
#include<string>
#include<algorithm>
#include<sstream>
#include<ctype.h>
#include<fstream>
#include<string.h>
#include<stdio.h>
#include<math.h>
#include<stack>
#include<queue>
#include<ctime>
//#include<conio.h>
using namespace std;

const int INF_MAX=0x7FFFFFFF;
const int INF_MIN=-(1<<30);

const double eps=1e-10;
const double pi=acos(-1.0);

#define pb push_back   //a.pb( )
#define chmin(a,b) ((a)<(b)?(a):(b))
#define chmax(a,b) ((a)>(b)?(a):(b))

template<class T> inline T gcd(T a,T b)//NOTES:gcd(
  {if(a<0)return gcd(-a,b);if(b<0)return gcd(a,-b);return (b==0)?a:gcd(b,a%b);}
template<class T> inline T lcm(T a,T b)//NOTES:lcm(
  {if(a<0)return lcm(-a,b);if(b<0)return lcm(a,-b);return a*(b/gcd(a,b));}

typedef pair<int, int> PII;
typedef vector<PII> VPII;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef long long LL;
int dir_4[4][2]={{0,1},{-1,0},{0,-1},{1,0}};
int dir_8[8][2]={{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{1,1}};
//下,左下,左,左上,上,右上,右,右下。

//******* WATER ****************************************************************

struct node {
    LL a, b;
    double d;
    bool operator < (const node& k) const{
        return a < k.a; //升序
    }
};

vector<node> vn;

LL calc() {
    LL mod = 365 * 24 * 60 * 60;
    LL ret = 0;
    LL sum = 0;
    for(int i = 0; i < vn.size(); i++) {
        ret = sum * vn[i].b + vn[i].a;
        sum += ret;
        sum %= mod;
    }
    return sum;
}

int main() {
    int n;
    node tmp;
    while(scanf("%d", &n) && n) {
        vn.clear();
        for(int i = 0; i < n; i++) { scanf("%I64d%I64d", &tmp.a, &tmp.b); tmp.d = (double)tmp.a / (tmp.b - 1);  vn.push_back(tmp);}
        //sort(vn.begin(), vn.end());
        printf("%I64d\n", calc());
    }
    return 0;
}
时间: 2024-11-02 11:42:51

HDU-4442-Physical Examination (2012年金华赛区现场赛A题)的相关文章

HDU 4435 charge-station (2012年天津赛区现场赛E题)

1.题目描述:点击打开链接 2.解题思路:本题利用DFS解决.不过本题的解法颇为巧妙,注意到2^0+2^1+...+2^(i-1)<2^i,这就意味着即使在0~i-1都建立加油站,费用也会小于单独在i处建立加油站.这就提示我们,可以一开始全部都建立加油站,然后从大到小依次尝试着删除加油站,如果可以删除,就删除,如果不可以,再添加上.那么该如何判断删除第i处之后是否可行呢?可以利用dfs判断,如果当前访问结点u是建立过加油站的,如果它的邻接点v也是建立了加油站的,且dist(u,v)<=d,那么

HDU 4455 Substrings (2012年杭州赛区现场赛C题)

1.题目描述:点击打开链接 2.解题思路:本题利用dp解决.不过这个dp的思路的确比太容易想到.需要观察规律才能发现.我们可以从贡献值的角度考虑.以题目中给的样例来说明这种方法. 通过观察相邻两个w值,我们会发现一个事实:每个大区间都包含了小区间的解(这里的解即原题中的sum值).但是这还不够,观察图上标记为红色的数字,它们可以看做是上一个w值对应的区间多出来的新数字,如果我们可以算出这些红色数字的贡献值,那么我们就能得到当前w下的解.那么该如何计算呢? 继续观察后会发现,每次w增加1,区间个数

HDU 4422 The Little Girl who Picks Mushrooms (2012年成都赛区现场赛C题)

1.题目描述:点击打开链接 2.解题思路:本题是一道简单模拟题,然而,自己的方法不对WA了很多次==.最后不得不弃用自己的思路了.首先用-1表示还没有使用过的位置.可以每次枚举3个位置,如果发现这3个位置中没有-1且他们的和不能被1024整除,那么return 0,否则,找到没有被标记的另外2个位置,如果这2个位置其中一个为-1,那么直接返回1024,因为我们已经交了三个袋子了,剩下的袋子中如果又没有确定的,那么一定可以凑成1024.否则,计算这2个位置的和,然后看减去若干次1024后剩下多少,

HDU 4458 Shoot the Airplane (2012年杭州赛区现场赛F题)

1.题目描述:点击打开链接 2.解题思路:本题利用运动的相对性解决.可以假设飞机固定不动,那么子弹相当于还有一个水平分量,只不过方向是-v.这样,问题就转化为一个动点什么时候到达一个多边形内部的问题了.不过本题有一个细节就是g可能等于0,因此要分匀变速运动和匀速运动2种情况求出最大可能的子弹飞行时间.另外一个细节就是本题对精度要求比较高,建议判断点是否在线段上改为利用坐标的差值来判断,避开使用Dot函数. 3.代码: #include<iostream> #include<algorit

HDU 4462 Scaring the Birds (2012年杭州赛区现场赛J题)

1.题目描述:点击打开链接 2.解题思路:本题是一道简单模拟题.不过重点还是对于题目细节的理解.容易犯2个理解错误:(1)误以为是每个稻草人有不同的scaring range,实际上scaring range是由不同的vacant intersection决定的,跟稻草人毫无关系.(2)误以为所有点都需要被覆盖,实际上题目要求的是只要所有corn被保护就行,插稻草人的地方本来就是空地,有没有被保护无所谓的.由于题目给的范围非常小,完全可以通过枚举集合来确定哪些位置需要稻草人,如果这些稻草人成功的

HDU 5128 The E-pang Palace(2014广州赛区现场赛B题 计算几何)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5128 解题报告:在一个平面上给出n个点的坐标,用这n个点作为矩形的四个顶点,作两个矩形,要求两个矩形不能相交,也不能有边和点相交,然后两个矩形的面积之和要最大,求最大的面积之和是多少?如果不存在输出imp 因为n <=30,所以可以先把所有的矩形枚举出来,然后再暴力判断两两矩形组合,首先要满足位置关系,然后取面积和最大就是了.要注意的地方就是要小心一个大矩形包含一个小矩形的情况,在这种情况下,是满足

HDU 5120 A Curious Matt(2014北京赛区现场赛A题 简单模拟)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5112 解题报告:扫一遍 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 const int maxn = 1e6+5; 8 9 struct node

hdu 4405 概率dp 2012年金华亚洲网络赛--虽然水,但是是自己独立做的第一道概率dp

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4405 e[i]:当前在位置i还需要走的步数期望 受刘汝佳的AC自动机那个后缀链接写法的启发,我的x[i]通过逆序算出来连续有"flight line "的时候,能到达的最远距离, rep(i,0,m) { scanf("%d%d",&xx,&yy); x[xx]=yy; } for(int i=n;i>=0;i--) if(x[i]!=-1 &

HDU 4119 Isabella&#39;s Message (2011年成都赛区现场赛I题)

1.题目描述:点击打开链接 2.解题思路:本题是一道模拟题,要求模拟一个解密的过程,练习这么久第一次做模拟题1Y了,内心还是很激动的~.只需要根据题意,记录* 所在的位置即可,然后每次都是先解密,后顺时针旋转90度.把每次解密的信息放到一个vector里,接下来就是连接它们,得到解密后的字符串,在map中查找这些单词是否存在即可.如果都存在,就把这条解密信息放到ans中,最后对ans排序,输出ans[0]就是答案. 3.代码: //#pragma comment(linker, "/STACK: