1. 程式人生 > >PAT甲級1028,1029解題報告

PAT甲級1028,1029解題報告

1028:

1028 List Sorting (25 分)

Excel can sort records according to any column. Now you are supposed to imitate this function.

Input Specification:

Each input file contains one test case. For each case, the first line contains two integers N (≤10​5​​) and C, where N is the number of records and C is the column that you are supposed to sort the records with. Then Nlines follow, each contains a record of a student. A student's record consists of his or her distinct ID (a 6-digit number), name (a string with no more than 8 characters without space), and grade (an integer between 0 and 100, inclusive).

Output Specification:

For each test case, output the sorting result in N lines. That is, if C = 1 then the records must be sorted in increasing order according to ID's; if C = 2 then the records must be sorted in non-decreasing order according to names; and if C = 3 then the records must be sorted in non-decreasing order according to grades. If there are several students who have the same name or grade, they must be sorted according to their ID's in increasing order.

Sample Input 1:

3 1
000007 James 85
000010 Amy 90
000001 Zoe 60

Sample Output 1:

000001 Zoe 60
000007 James 85
000010 Amy 90

Sample Input 2:

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

Sample Output 2:

000010 Amy 90
000002 James 98
000007 James 85
000001 Zoe 60

Sample Input 3:

4 3
000007 James 85
000010 Amy 90
000001 Zoe 60
000002 James 90

Sample Output 3:

000001 Zoe 60
000007 James 85
000002 James 90
000010 Amy 90

題目大意:輸入總人數和tag,然後每個人的學號,姓名,成績,要求按照tag的不同用不同方式排序得出排序結果。

解題思路:水題,排序排一下輸出一下。

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<time.h>
#include<math.h>
#include<set>
#include<map>
using namespace std;
struct stu {
	string id;
	string name;
	int grade;
};
bool Cmp1(stu a,stu b){
	return a.id < b.id;
}
bool Cmp2(stu a, stu b) {
	if (a.name < b.name)return true;
	else if (a.name == b.name)return a.id < b.id;
	else return false;
}
bool Cmp3(stu a, stu b) {
	if (a.grade < b.grade)return true;
	else if (a.grade == b.grade)return a.id < b.id;
	else
		return false;
}
vector<stu> cur;
int main()
{
	int n, k;
	cin >> n >> k;
	for (int i = 0; i < n; i++) {
		stu tmp;
		cin >> tmp.id >> tmp.name >> tmp.grade;
		cur.push_back(tmp);
	}
	if (k == 1) {
		sort(cur.begin(), cur.end(), Cmp1);
	}
	else if (k == 2) {
		sort(cur.begin(), cur.end(), Cmp2);
	}
	else {
		sort(cur.begin(), cur.end(), Cmp3);
	}
	for (int i = 0; i < cur.size(); i++) {
		cout << cur[i].id << " " << cur[i].name << " " << cur[i].grade << endl;
	}
	return 0;
}

1029:

1029 Median (25 分)

Given an increasing sequence S of N integers, the median is the number at the middle position. For example, the median of S1 = { 11, 12, 13, 14 } is 12, and the median of S2 = { 9, 10, 15, 16, 17 } is 15. The median of two sequences is defined to be the median of the nondecreasing sequence which contains all the elements of both sequences. For example, the median of S1 and S2 is 13.

Given two increasing sequences of integers, you are asked to find their median.

Input Specification:

Each input file contains one test case. Each case occupies 2 lines, each gives the information of a sequence. For each sequence, the first positive integer N (≤2×10​5​​) is the size of that sequence. Then N integers follow, separated by a space. It is guaranteed that all the integers are in the range of long int.

Output Specification:

For each test case you should output the median of the two given sequences in a line.

Sample Input:

4 11 12 13 14
5 9 10 15 16 17

Sample Output:

13

題目大意:給兩串序列(n<=2e5),輸出兩串序列之間的中序數,每個資料不超出long int。

解題思路:在參考他人部落格之前,沒做對過,最高16.思路歷程:

1.第一眼看到,沒管直接STL裡面list,因為很像資料結構基礎題兩個有序連結串列的合併,16分,gg。記憶體超出限制。

2.然後發現了題目的long int,第一眼的時候認為long int一定是4位的,因為感覺現代的個人PC,long int 和int是一樣的,都是四位,然後是4*4e5的極端情況最後是應該不會超出1.5MB。

3.後來用類似注入的方法。。故意製造死迴圈。發現PAT系統的機器long int是8位的。。那肯定是超出限制了。也就是暗示我們在資料量極大的情況下,不能把兩個陣列全部讀完。

4.然後一籌莫展的情況下,去參考了他人的題解,大多數的題解都是錯誤的。直到看到一個考慮到記憶體因素的。

5.看到用佇列維護就有想法了,思路其實很簡單,把第一個陣列a讀完,並在最後設定一個哨兵。不需要用long int存。long int怎麼樣都是超時的,把long int當成int處理就是了。哨兵為了方便,直接賦值最大的int。可以確定中序數是res=(n1+n2)%2!=0?(n1+n2)/2+1:(n1+n2)/2個;

6.然後維護佇列,再讀第二個陣列b的時候,每讀一個,把a,b中小的那個隊頭pop出去,直到要push第res個時候,把最終的結果輸出。

7.考慮到可能是第二個陣列比較短。所以要設定一個標誌,如果還沒有找到這個res結果,那麼就繼續累加,不斷pop出a,b中的表頭最小者直到輸出。

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<time.h>
#include<math.h>
#include<set>
#include<map>
#include<list>
#include<climits>
#include<queue>
using namespace std;
queue<int> a, b;
int main()
{
	int n1,n2;
	cin >> n1;
	for (int i = 0; i < n1; i++) {
		int num;
		cin >> num;
		a.push(num);
	}
	a.push(INT_MAX);
	cin >> n2;
	int index=0;
	int res = (n1 + n2) % 2 != 0 ? (n1 + n2) / 2 : (n1 + n2) / 2 - 1;
	int ans;
	bool flag = false;
	for (int i = 0; i < n2; i++) {
		int num;
		cin >> num;
		b.push(num);
		if (index == res) {
			ans=min(a.front(), b.front());
			flag = true;
			break;
		}
		if (a.front() < b.front())
			a.pop();
		else
			b.pop();
		index++;
	}
	if (flag) {
		cout << ans << endl;
	}
	else {
		b.push(INT_MAX);
		for (; index < res; index++) {
			if (a.front() < b.front())
				a.pop();
			else
				b.pop();
		}

		cout << min(a.front(), b.front()) << endl;
	}
	return 0;
}

題目的那個long int是真的坑。。