程序设计算法竞赛基础——练习2解题报告

程序设计算法竞赛基础——练习2解题报告

1001 sort

Problem Description

给你n个整数,请按从大到小的顺序输出其中前m大的数。

Input

每组测试数据有两行,第一行有两个数n,m(0

Output

对每组测试数据按从大到小的顺序输出前m大的数。

Sample Input

5 3
3 -35 92 213 -644

Sample Outple

213 92 3

Author

LL

Source

ACM暑假集训队练习赛(三)

解题思路

输出n个数中最大的m个数,可以通过多种方法实现,但是由于数据量比较多,使用cin或cout可能导致超时。

代码实现

#include

const int maxn = 1000005;
int a[maxn];
//将m定义为全局变量可表示还需要输出多少数,heapsize用于存储每次输出后剩下数的数量
int heapsize, m;

//用于交换位置
void exchange(const int x, const int y){
	int temp = a[x];
	a[x] = a[y];
	a[y] = temp;
}

//将数组中i~heapsize间的数据进行从大到小的堆排序
void heap_max(const int i) {
	int left = i * 2;
	int right = left + 1;
	int max2;
	if(left <= heapsize && a[left] > a[i]) max2= left;
	else max2 = i;
	if(right <= heapsize && a[max2] < a[right])max2 = right;
	if(max2 != i) {
		exchange(i, max2);
		heap_max(max2);
	}
}

int main() {
	int n;
    
	while((scanf("%d %d", &n, &m) != EOF)) {
		for(int i = 1; i <= n; i++) {
			scanf("%d", &a[i]);
		}
        //将heapsize初始化为n
		heapsize = n;
        
        //将整个数组进行堆排序
		for(int i = n / 2; i >= 1; i--) {
			heap_max(i);
		}
        
        //先输出最大数并m--
		printf("%d", a[1]);
		m--;
        
        //重新排序再输出下一个最大数,直到m为0时停止
		while(m){
			for(int i = n; i >= 2; i--){
				heapsize--;
				exchange(i, 1);
				heap_max(1);
				printf(" %d", a[1]);
				m--;
				if(m == 0)break;
			}
		}
		printf("\n");
	}
	return 0;
}

1002 EXCEL排序

Problem Description

Excel可以对一组纪录按任意指定列排序。现请你编写程序实现类似功能。

Input

测试输入包含若干测试用例。每个测试用例的第1行包含两个整数 N (<=100000) 和 C,其中 N 是纪录的条数,C 是指定排序的列号。以下有 N
行,每行包含一条学生纪录。每条学生纪录由学号(6位数字,同组测试中没有重复的学号)、姓名(不超过8位且不包含空格的字符串)、成绩(闭区间[0, 100]内的整数)组成,每个项目间用1个空格隔开。当读到 N=0 时,全部输入结束,相应的结果不要输出。

Output

对每个测试用例,首先输出1行“Case i:”,其中 i 是测试用例的编号(从1开始)。随后在 N 行中输出按要求排序后的结果,即:当 C=1 时,按学号递增排序;当 C=2时,按姓名的非递减字典序排序;当 C=3
时,按成绩的非递减排序。当若干学生具有相同姓名或者相同成绩时,则按他们的学号递增排序。

Sample Input

3 1
000007 James 85
000010 Amy 90
000001 Zoe 60
4 2
000007 James 85
000010 Amy 90
000001 Zoe 60
000002 James 98
4 3
000007 James 85
000010 Amy 90
000001 Zoe 60
000002 James 90
0 0

Sample Output

Case 1:
000001 Zoe 60
000007 James 85
000010 Amy 90
Case 2:
000010 Amy 90
000002 James 98
000007 James 85
000001 Zoe 60
Case 3:
000001 Zoe 60
000007 James 85
000002 James 90
000010 Amy 90

Source

浙大计算机研究生复试上机考试-2007年

解题思路

使用结构体存储数据,根据C的不同值为sort传入不同参数进行排序

代码实现

#include
#include
#include
#include
using namespace std;

struct INF {
	int mum;
	char name[10];
	int gar;
};

vector a;

//C为1时
bool cmp1(INF x, INF y) {
	return x.mum < y.mum;
}

//C为2时
bool cmp2(INF x, INF y) {
	if((strcmp(x.name, y.name)) > 0) return false;
	else if((strcmp(x.name, y.name)) < 0) return true;
	else return x.mum < y.mum;
}

//C为3时
bool cmp3(INF x, INF y) {
	if(x.gar != y.gar) return x.gar < y.gar;
	else return x.mum < y.mum;
}

int main() {
	int n, c, kase = 0;
	while(scanf("%d %d", &n, &c) == 2 && n != 0 && c != 0) {
		kase++;
		a.clear();
		while(n--) {
			INF temp;
			scanf("%d %s %d", &temp.mum, temp.name, &temp.gar);
			a.push_back(temp);
		}
        //判断C的值进行不同的排序
		if(c == 1) sort(a.begin(), a.end(), cmp1);
		else if(c == 2) sort(a.begin(), a.end(), cmp2);
		else sort(a.begin(), a.end(), cmp3);
		printf("Case %d:\n", kase);
		for(INF temp: a) {
			printf("%06d %s %d\n", temp.mum, temp.name, temp.gar);
		}
	}
	return 0;
}

1003 Design T-Shirt

Problem Description

Soon after he decided to design a T-shirt for our Algorithm Board on Free-City BBS, XKA found that he was trapped by all kinds of suggestions from everyone on the board. It is indeed a mission-impossible to have everybody perfectly satisfied. So he took a poll to collect people’s opinions. Here are what he obtained: N people voted for M design elements (such as the ACM-ICPC logo, big names in computer science, well-known graphs, etc.). Everyone assigned each element a number of satisfaction. However, XKA can only put K (<=M) elements into his design. He needs you to pick for him the K elements such that the total number of satisfaction is maximized.

Input

The input consists of multiple test cases. For each case, the first line contains three positive integers N, M and K where N is the number of people, M is the number of design elements, and K is the number of elements XKA will put into his design. Then N lines follow, each contains M numbers. The j-th number in the i-th line represents the i-th person’s satisfaction on the j-th element.

Output

For each test case, print in one line the indices of the K elements you would suggest XKA to take into consideration so that the total number of satisfaction is maximized. If there are more than one solutions, you must output the one with minimal indices. The indices start from 1 and must be printed in non-increasing order. There must be exactly one space between two adjacent indices, and no extra space at the end of the line.

Sample Input

3 6 4
2 2.5 5 1 3 4
5 1 3.5 2 2 2
1 1 1 1 1 10
3 3 2
1 2 3
2 3 1
3 1 2

Sample Output

6 5 3 1
2 1

Author

CHEN, Yue

Source

CYJJ’s Funny Contest #1, Killing in Seconds

解题思路

注意满意度不一定为整数且输出时logo号码应该以降序排列

代码实现

#include
#include
#include
using namespace std;

//sum保存满意度,mum保存logo号码
struct INF {
	int mum;
	double sum = 0.0;
};

//根据满意度降序,满意度相同时小号在前
bool cmp1(const INF x, const INF y) {
	if(x.sum != y.sum) return x.sum > y.sum;
	else return x.mum < y.mum;
}

//logo序号降序
bool cmp2(const INF x, const INF y) {
	return x.mum > y.mum;
}

int main() {
	int n, m, k;
	while(cin >> n >> m >> k) {
		INF a[m];
		for(int i = 0; i < n; i++) {
			for(int j = 0; j < m; j++) {
				double temp;
				cin >> temp;
				a[j].sum += temp;
				a[j].mum = j + 1;
			}
		}
        //所有logo按满意度降序排列
		sort(a, a + m, cmp1);
        //将满意度前k的logo按号码降序排列
		sort(a, a + k, cmp2);
		bool t = true;
		for(int i = 0; i < k; i++) {
			if(t) t = false;
			else cout << " ";
			cout << a[i].mum;
		}
		cout << endl;
	}
	return 0;
}

1004 稳定排序

Problem Description

大家都知道,快速排序是不稳定的排序方法。
如果对于数组中出现的任意a[i],aj,其中a[i]==a[j],在进行排序以后a[i]一定出现在a[j]之前,则认为该排序是稳定的。

某高校招生办得到一份成绩列表,上面记录了考生名字和考生成绩。并且对其使用了某排序算法按成绩进行递减排序。现在请你判断一下该排序算法是否正确,如果正确的话,则判断该排序算法是否为稳定的。

Input

本题目包含多组输入,请处理到文件结束。
对于每组数据,第一行有一个正整数N(0 接下来有N行,每一行有一个字符串代表考生名字(长度不超过50,仅包含’a’~‘z’),和一个整数代表考生分数(小于500)。其中名字和成绩用一个空格隔开。
再接下来又有N行,是上述列表经过某排序算法以后生成的一个序列。格式同上。

Output

对于每组数据,如果算法是正确并且稳定的,就在一行里面输出"Right"。如果算法是正确的但不是稳定的,就在一行里面输出"Not Stable",并且在下面输出正确稳定排序的列表,格式同输入。如果该算法是错误的,就在一行里面输出"Error",并且在下面输出正确稳定排序的列表,格式同输入。

注意,本题目不考虑该排序算法是错误的,但结果是正确的这样的意外情况。

Sample Input

3
aa 10
bb 10
cc 20
cc 20
bb 10
aa 10
3
aa 10
bb 10
cc 20
cc 20
aa 10
bb 10
3
aa 10
bb 10
cc 20
aa 10
bb 10
cc 20

Sample Output

Not Stable
cc 20
aa 10
bb 10
Right
Error
cc 20
aa 10
bb 10

Author

linle

Source

2008浙大研究生复试热身赛(2)——全真模拟

解题思路

使用两个结构体数组分别存储排序前和排序后的数据,将排序前的进行排序然后与排序后的比较

代码实现

#include
#include
#include
using namespace std;

struct INF {
	char name[55];
	int mum;
	int k;
};

//分数降序 -> 输入顺序升序 
bool cmp(const INF x, const INF y) {
	if(x.mum != y.mum)return x.mum > y.mum;
	else return x.k < y.k;
}

int main() {
	int n;
	while(cin >> n) {
		INF a[n], tr[n];
		for(int i = 0; i < n; i++) {
			cin >> a[i].name >> a[i].mum;
			a[i].k = i;
		}
		sort(a, a + n, cmp);
		for(int i = 0; i < n; i++) {
			cin >> tr[i].name >> tr[i].mum;
		}
		//kase为2时正确,为1时不稳定,为0时错误 
		int kase = 2;
		for(int i = 0; i < n; i++) {
			if(strcmp(a[i].name, tr[i].name) != 0) kase = 1;
			if(a[i].mum != tr[i].mum) kase = 0;
			if(kase == 0) break;
		}
		if(kase == 2) cout <<"Right" << endl;
		else {
			if(kase == 1) cout << "Not Stable" << endl;
			else cout << "Error" << endl;
			for(int i = 0; i < n; i++) {
				cout << a[i].name << " " << a[i].mum << endl;
			}
		}
	}
	return 0;
}

1005 FatMouse’ Trade

Problem Description

FatMouse prepared M pounds of cat food, ready to trade with the cats guarding the warehouse containing his favorite food, JavaBean.
The warehouse has N rooms. The i-th room contains J[i] pounds of JavaBeans and requires F[i] pounds of cat food. FatMouse does not have to trade for all the JavaBeans in the room, instead, he may get J[i]* a% pounds of JavaBeans if he pays F[i]* a% pounds of cat food. Here a is a real number. Now he is assigning this homework to you: tell him the maximum amount of JavaBeans he can obtain.

Input

The input consists of multiple test cases. Each test case begins with a line containing two non-negative integers M and N. Then N lines follow, each contains two non-negative integers J[i] and F[i] respectively. The last test case is followed by two -1’s. All integers are not greater than 1000.

Output

For each test case, print in a single line a real number accurate up to 3 decimal places, which is the maximum amount of JavaBeans that FatMouse can obtain.

Sample Input

5 3
7 2 2
4 3
5 2
20 3
25 18
24 15
15 10
-1 -1

Sample Output

13.333
31.500

Author

CHEN, Yue

Source

ZJCPC2004

解题思路

注意输出格式,将每个房间按单位猫粮能换取的java豆降序排序,注意每个房间java豆是有上限的即可

代码实现

#include
#include
using namespace std;

struct INF {
	int get;
	int give;
	double temp;
	//INF类型的ab.temp 
	bool operator < (const INF& a)const {
		return a.temp < temp;
	}
};

int main() {
	int m, n;
	while((scanf("%d %d", &m, &n)) == 2 && m != -1 && n != -1) {
		INF room[n];
		for(int i = 0; i < n; i++) {
			scanf("%d %d", &room[i].get, &room[i].give);
			room[i].temp = room[i].get * 1.0 / room[i].give;
		}
		sort(room, room + n);
		double sum = 0.0;
		for(int i = 0; i < n; i++) {
            //剩余猫粮大于房间最大给出猫粮时全交换
			if(m > room[i].give) {
				sum += room[i].get;
				m -= room[i].give;
			}
            //剩余猫粮小于等于房间最大给出猫粮时为最后一次交换
			else {
				sum += m * room[i].temp;
				break;
			}
		}
		printf("%.3f\n", sum);
	}
	return 0;
}

1006 Tian Ji – The Horse Racing

Problem Description

Here is a famous story in Chinese history.

“That was about 2300 years ago. General Tian Ji was a high official in the country Qi. He likes to play horse racing with the king and others.”

“Both of Tian and the king have three horses in different classes, namely, regular, plus, and super. The rule is to have three rounds in a match; each of the horses must be used in one round. The winner of a single round takes two hundred silver dollars from the loser.”

“Being the most powerful man in the country, the king has so nice horses that in each class his horse is better than Tian’s. As a result, each time the king takes six hundred silver dollars from Tian.”

“Tian Ji was not happy about that, until he met Sun Bin, one of the most famous generals in Chinese history. Using a little trick due to Sun, Tian Ji brought home two hundred silver dollars and such a grace in the next match.”

“It was a rather simple trick. Using his regular class horse race against the super class from the king, they will certainly lose that round. But then his plus beat the king’s regular, and his super beat the king’s plus. What a simple trick. And how do you think of Tian Ji, the high ranked official in China?”

田忌赛马

Were Tian Ji lives in nowadays, he will certainly laugh at himself. Even more, were he sitting in the ACM contest right now, he may discover that the horse racing problem can be simply viewed as finding the maximum matching in a bipartite graph. Draw Tian’s horses on one side, and the king’s horses on the other. Whenever one of Tian’s horses can beat one from the king, we draw an edge between them, meaning we wish to establish this pair. Then, the problem of winning as many rounds as possible is just to find the maximum matching in this graph. If there are ties, the problem becomes more complicated, he needs to assign weights 0, 1, or -1 to all the possible edges, and find a maximum weighted perfect matching…

However, the horse racing problem is a very special case of bipartite matching. The graph is decided by the speed of the horses — a vertex of higher speed always beat a vertex of lower speed. In this case, the weighted bipartite matching algorithm is a too advanced tool to deal with the problem.

In this problem, you are asked to write a program to solve this special case of matching problem.

Input

The input consists of up to 50 test cases. Each case starts with a positive integer n (n <= 1000) on the first line, which is the number of horses on each side. The next n integers on the second line are the speeds of Tian’s horses. Then the next n integers on the third line are the speeds of the king’s horses. The input ends with a line that has a single 0 after the last test case.

Output

For each input case, output a line containing a single number, which is the maximum money Tian Ji will get, in silver dollars.

Sample Input

3
92 83 71
95 87 74
2
20 20
20 20
2
20 19
22 18
0

Sample Outple

200
0
0

Source

2004 Asia Regional Shanghai

解题思路

本题情况较多,需要考虑全面

样例不够典型,下面有几个典型样例

3
1 2 3
1 2 3
3
20 20 20
20 20 20
3
99 99 2
99 98 1
3
99 50 2
90 50 1
0

代码实现

#include
#include
using namespace std;

//降序
bool cmp(const int a, const int b) {
	return a < b;
}

int main() {
	int n;
	while((scanf("%d", &n) == 1) && n != 0) {
		int horse[n], hor[n];
		for(int i = 0; i < n; i++) {
			scanf("%d", &horse[i]);
		}
		for(int i = 0; i < n; i++) {
			scanf("%d", &hor[i]);
		}
		sort(horse, horse + n, cmp);
		sort(hor, hor + n, cmp);
		//win赢场 lose输场 left田忌慢马 right田忌快马 le齐王慢马 rig齐王快马
		int win = 0, lose = 0;
		int le = 0, rig = n - 1;
		int left = 0, right = n - 1;
		while(le <= rig) {
			if(horse[right] > hor[rig]) {
				//以优胜优
				win++;
				right--;
				rig--;
			} else if(horse[right] < hor[rig]) {
				//优不及,以劣换优
				lose++;
				left++;
				rig--;
			} else {
				//优一致,取决劣 
				if(horse[left] > hor[le]) {
					//以劣胜劣
					win++;
					left++;
					le++;
				} else if(horse[left] < hor[le]) {
					//劣不及,以劣换优
					lose++;
					left++;
					rig--;
				} else {
					//劣一致,以劣战优
					if(horse[left] < hor[rig]) {
						//战败lose++
						lose++;
					}
					left++;
					rig--;
				}
			}
		}
		int sum = (win - lose) * 200;
		printf("%d\n", sum);
	}
	return 0;
}

1007 Moving Tables

Problem Description

The famous ACM (Advanced Computer Maker) Company has rented a floor of a building whose shape is in the following figure.

走廊

The floor has 200 rooms each on the north side and south side along the corridor. Recently the Company made a plan to reform its system. The reform includes moving a lot of tables between rooms. Because the corridor is narrow and all the tables are big, only one table can pass through the corridor. Some plan is needed to make the moving efficient. The manager figured out the following plan: Moving a table from a room to another room can be done within 10 minutes. When moving a table from room i to room j, the part of the corridor between the front of room i and the front of room j is used. So, during each 10 minutes, several moving between two rooms not sharing the same part of the corridor will be done simultaneously. To make it clear the manager illustrated the possible cases and impossible cases of simultaneous moving.

分析

For each room, at most one table will be either moved in or moved out. Now, the manager seeks out a method to minimize the time to move all the tables. Your job is to write a program to solve the manager’s problem.

Input

The input consists of T test cases. The number of test cases ) (T is given in the first line of the input. Each test case begins with a line containing an integer N , 1<=N<=200 , that represents the number of tables to move. Each of the following N lines contains two positive integers s and t, representing that a table is to move from room number s to room number t (each room number appears at most once in the N lines). From the N+3-rd line, the remaining test cases are listed in the same manner as above.

Output

The output should contain the minimum time in minutes to complete the moving, one per line.

Sample Input

3 
4 
10 20 
30 40 
50 60 
70 80 
2 
1 3 
2 200 
3 
10 100 
20 80 
30 50 

Sample Output

10
20
30

Source

Asia 2001, Taejon (South Korea)

解题思路

400个房间对称分布,只需定义一个200位大小的数组存放存过该点次数即可,输出数组中最大值*10分钟即为所求

代码实现

#include
#include
using namespace std;

int room[200];

int minn(const int a, const int b) {
	if(a < b) return a;
	else return b;
}

int maxn(const int a, const int b) {
	if(a > b) return a;
	else return b;
}

int main() {
	int c;
	cin >> c;
	while(c--) {
		int n;
		cin >> n;
		int max = 0;
		memset(room, 0, sizeof(room));
		while(n--) {
			int s, t;
			cin >> s >> t;
            //搬桌子可能从小号码房间搬到大号码也可能大号码搬到小号码
            //left存储小号码,right存储大号码
			int left = (minn(s, t) - 1) / 2;
			int right = (maxn(s, t) - 1) / 2;
			for(int i = left; i <= right; i++) {
				room[i]++;
				if(max < room[i]) max = room[i];
			}
		}
		cout << max * 10 << endl;
	}
	return 0;
}

1008 今年暑假不AC

Problem Description

“今年暑假不AC?”
“是的。”
“那你干什么呢?”
“看世界杯呀,笨蛋!”
“@#$%^&*%…”

确实如此,世界杯来了,球迷的节日也来了,估计很多ACMer也会抛开电脑,奔向电视了。
作为球迷,一定想看尽量多的完整的比赛,当然,作为新时代的好青年,你一定还会看一些其它的节目,比如新闻联播(永远不要忘记关心国家大事)、非常6+7、超级女生,以及王小丫的《开心辞典》等等,假设你已经知道了所有你喜欢看的电视节目的转播时间表,你会合理安排吗?(目标是能看尽量多的完整节目)

Input

输入数据包含多个测试实例,每个测试实例的第一行只有一个整数n(n<=100),表示你喜欢看的节目的总数,然后是n行数据,每行包括两个数据Ti_s,Ti_e (1<=i<=n),分别表示第i个节目的开始和结束时间,为了简化问题,每个时间都用一个正整数表示。n=0表示输入结束,不做处理。

Output

对于每个测试实例,输出能完整看到的电视节目的个数,每个测试实例的输出占一行。

Sample Input

12
1 3
3 4
0 7
3 8
15 19
15 20
10 15
8 18
6 12
5 10
4 14
2 9
0

Sample Output

5

Author

Icy

Source

ACM程序设计期末考试(2006/06/07)

解题思路

将一天中的节目按开始时间升序排列好,然后从第一个开始看,如果发现新节目比真正看的节目先结束,那就直接去看新节目,如果在新节目开始前正在看的节目已经结束或刚好结束那就看过的节目数量+1

代码实现

#include
#include
using namespace std;

struct INF{
	int start;
	int end;
	
    //按开始时间升序排列,开始时间一致时按结束时间升序
	bool operator < (const INF& a) const{
		if(start != a.start) return start < a.start;
		else return end < a.end;
	}
};

int main(){
	int n;
	while(cin >> n && n != 0){
		INF mum[n];
		for(int i = 0; i < n; i++){
			cin >> mum[i].start >> mum[i].end;
		}
		sort(mum, mum + n);
		int kase = 0;
		int st = mum[0].start, en = mum[0].end;
		for(int i = 1; i < n; i++){
            //节目开始前前一个节目已经结束了
			if(en <= mum[i].start){
				kase++;
				st = mum[i].start;
				en = mum[i].end;
			} else {
                //虽然前一个节目未结束,但新节目结束时间比前一个节目还早
                //舍弃前一个节目换新节目
				if(en > mum[i].end){
					st = mum[i].start;
					en = mum[i].end;
				}
			}
		}
		cout << kase + 1 << endl;
	}
	return 0;
}

1009 Max Sum

Problem Description

Given a sequence a1,a2,a3…a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14.

Input

The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line starts with a number N(1<=N<=100000), then N integers followed(all the integers are between -1000 and 1000).

Output

For each test case, you should output two lines. The first line is “Case #:”, # means the number of the test case. The second line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence. If there are more than one result, output the first one. Output a blank line between two cases.

Sample Input

2
5 6 -1 5 4 -7
7 0 6 -1 1 -6 7 -5

Sample Output

Case 1:
14 1 4

Case 2:
7 1 6

Author

Ignatius.L

解题思路

注意每个案例中间需要隔一行输出且最后一个案例不再需要隔一行

代码实现

#include

int main(){
	int t;
	scanf("%d", &t);
	for(int kase = 1; kase <= t; kase++){
		int n;
		scanf("%d", &n);
		//sum存储a[tp,i]的数据和,maxsum存储a[left,right]中最大的那段数据和
		long long maxsum = -10000, sum = 0;
		int tp = 1, left = 0, right = 0;
		for(int i = 1; i <= n; i++){
			int temp;
			scanf("%d", &temp);
			sum += temp;
            //如果sum段大于maxsum段说明最大段为sum段
			if(sum >= maxsum){
				maxsum = sum;
				left = tp;
				right = i;
			}
            //sum段已经总和小于0了,这段完全可以丢弃了
			if(sum < 0){
				sum = 0;
				tp = i + 1;
			}
		}
		printf("Case %d:\n", kase);
		printf("%d %d %d\n", maxsum, left, right);
        //每个案例之间隔一行输出
		if(kase != t) printf("\n");
	}
	return 0;
}

1010 Saving HDU

Problem Description

话说上回讲到海东集团面临内外交困,公司的元老也只剩下XHD夫妇二人了。显然,作为多年拼搏的商人,XHD不会坐以待毙的。
一天,当他正在苦思冥想解困良策的时候,突然想到了自己的传家宝,那是公司成立的时候,父亲作为贺礼送来的一个锦囊,徐父当时交代,不到万不得已的时候,不要打开它。“现在不正是最需要的时候吗?”,一边想,XHD一边找到了这个精心保管的锦囊,打开一看,里面只有一句话“杭城北麓千人洞有宝”。
二话不说,XHD拿起一个大口袋就出发了,这个千人洞他是知道的,小的时候,爸爸曾经带他来过这个隐蔽的路口,并告诉他,这是千人洞。他现在才明白爸爸当初这句话的含义。
尽管有点印象,XHD还是花了很大的精力才找到这个异常隐蔽的洞口,走进一看,几乎惊呆了,真的是眼花缭乱!不过尽管宝贝的种类不少,但是每种宝贝的量并不多,当然,每种宝贝单位体积的价格也不一样,为了挽救HDU,现在请你帮忙尽快计算出来XHD最多能带回多少价值的宝贝?(假设宝贝可以分割,分割后的价值和对应的体积成正比)

Input

输入包含多个测试实例,每个实例的第一行是两个整数v和n(v,n<100),分别表示口袋的容量和宝贝的种类,接着的n行每行包含2个整数pi和mi(0

Output

对于每个测试实例,请输出XHD最多能取回多少价值的宝贝,每个实例的输出占一行。

Sample Input

2 2
3 1
2 3
0

Sample Output

5

Author

Icy

Source

ACM程序设计_期末考试

解题思路

按宝贝单价降序然后依次拿即可

代码实现

#include
#include
using namespace std;

//s存放全带走某宝贝会得到多少价值
struct INF {
	int pi;
	int mi;
	int s;

	bool operator < (const INF& a) const {
		if(pi != a.pi) return pi > a.pi;
		else return mi > a.mi;
	}
};

int main() {
	int v, n;
	while(cin >> v && v != 0) {
		cin >> n;
		INF mum[n];
		for(int i = 0; i < n; i++) {
			cin >> mum[i].pi >> mum[i].mi;
			mum[i].s = mum[i].pi * mum[i].mi;
		}
		sort(mum, mum + n);
		int sum = 0;
		for(int i = 0; i < n; i++) {
            //剩余容积大于等于某宝贝总大小,全部带走
			if(v >= mum[i].mi) {
				v -= mum[i].mi;
				sum += mum[i].s;
			} else {
                //剩余容积只能带走宝贝一部分
				sum += v * mum[i].pi;
				v = 0;
			}
			if(v == 0) break;
		}
		cout << sum << endl;
	}
	return 0;
}

你可能感兴趣的:(练习)