1026. Table Tennis (30)

1.整体思路为:先遍历vip桌子和vip玩家,如果有匹配成功的,进行匹配;然后再遍历一轮所有的桌子和等候的玩家,有匹配的进行匹配;

2.被卡的地方:

1)关于秒的四舍五入,是按照大于等于30秒,进一分钟,小于30秒则舍去的原则;最后的一个测试用例就是检验这个30秒的
2)在遍历所有的玩家时,由于可能存在已经被前面服务了的vip玩家,所以需要额外加一个处理,使得playIndex指向的是未被服务的玩家;
3)主要是忘记了遍历vip玩家时,同样存在2)中的问题,因为在遍历所有玩家的时候,有可能vip玩家也被服务安排了,所以需要在遍历vip玩家中加一个处理,使得vipIndex指向未被服务的vip玩家。

3.下面是一些比较重要的测试用例:


//边缘测试例子

1
21:00:00 10 1
3 3
1 2 3

1
20:59:59 10 1
3 3
1 2 3

0
3 1
2

//vip桌子分配例子,有vip桌子时,优先把vip分到编号小的vip桌子,而不是编号小的vip桌子
4
06:00:00 30 1
08:00:00 30 1
10:00:00 30 1
12:00:00 30 1
5 1
3
答案为:
06:00:00 08:00:00 120
08:00:00 08:00:00 0
10:00:00 10:00:00 0
12:00:00 12:00:00 0
1 0 3 0 0

//超过两小时的例子
2
18:00:00 180 1
20:00:00 60 1
1 1
1
答案为:
18:00:00 18:00:00 0
20:00:00 20:00:00 0
2

//关于四舍五入为1分钟的例子,大约等于30秒才+1分钟,小于30则不+
3
07:59:31 60 1
07:59:29 60 1
08:00:30 100 1
2 1
1
答案为:
1
07:59:29 08:00:00 1
07:59:31 08:00:00 0
08:00:30 09:00:00 60
2 1

时间限制
400 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

A table tennis club has N tables available to the public. The tables are numbered from 1 to N. For any pair of players, if there are some tables open when they arrive, they will be assigned to the available table with the smallest number. If all the tables are occupied, they will have to wait in a queue. It is assumed that every pair of players can play for at most 2 hours.

Your job is to count for everyone in queue their waiting time, and for each table the number of players it has served for the day.

One thing that makes this procedure a bit complicated is that the club reserves some tables for their VIP members. When a VIP table is open, the first VIP pair in the queue will have the priviledge to take it. However, if there is no VIP in the queue, the next pair of players can take it. On the other hand, if when it is the turn of a VIP pair, yet no VIP table is available, they can be assigned as any ordinary players.

Input Specification:

Each input file contains one test case. For each case, the first line contains an integer N (<=10000) – the total number of pairs of players. Then N lines follow, each contains 2 times and a VIP tag: HH:MM:SS – the arriving time, P – the playing time in minutes of a pair of players, and tag – which is 1 if they hold a VIP card, or 0 if not. It is guaranteed that the arriving time is between 08:00:00 and 21:00:00 while the club is open. It is assumed that no two customers arrives at the same time. Following the players’ info, there are 2 positive integers: K (<=100) – the number of tables, and M (< K) – the number of VIP tables. The last line contains M table numbers.

Output Specification:

For each test case, first print the arriving time, serving time and the waiting time for each pair of players in the format shown by the sample. Then print in a line the number of players served by each table. Notice that the output must be listed in chronological order of the serving time. The waiting time must be rounded up to an integer minute(s). If one cannot get a table before the closing time, their information must NOT be printed.

Sample Input:

9
20:52:00 10 0
08:00:00 20 0
08:02:00 30 0
20:51:00 10 0
08:10:00 5 0
08:12:00 10 1
20:50:00 10 0
08:01:30 15 1
20:53:00 10 1
3 1
2

Sample Output:

08:00:00 08:00:00 0
08:01:30 08:01:30 0
08:02:00 08:02:00 0
08:12:00 08:16:30 5
08:10:00 08:20:00 10
20:50:00 20:50:00 0
20:51:00 20:51:00 0
20:52:00 20:52:00 0
3 3 2

AC代码:

//#include<string>
//#include <iomanip>
#include<vector>
#include <algorithm>
//#include<stack>
#include<set>
#include<queue>
#include<map>
//#include<unordered_set>
//#include<unordered_map>
//#include <sstream>
//#include "func.h"
//#include <list>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
using namespace std;
#define maxServe 46810
/*
//正常的检测例子,全部为普通玩家
9
20:52:00 10 0
08:00:00 20 0
08:02:00 30 0
20:51:00 10 0
08:10:29 5 0
08:12:00 10 0
20:50:00 10 0
08:01:30 15 0
20:53:00 10 0
3 1
2
答案为:
08:00:00 08:00:00 0
08:01:30 08:01:30 0
08:02:00 08:02:00 0
08:10:29 08:16:30 6
08:12:00 08:20:00 8
20:50:00 20:50:00 0
20:51:00 20:51:00 0
20:52:00 20:52:00 0
3 3 2

//正常的测试例子,没有vip table
9
20:52:00 10 0
08:00:00 20 0
08:02:00 30 0
20:51:00 10 0
08:10:00 5 0
08:12:00 10 1
20:50:00 10 0
08:01:30 15 1
20:53:00 10 1
3 0
答案为:
08:00:00 08:00:00 0
08:01:30 08:01:30 0
08:02:00 08:02:00 0
08:10:00 08:16:30 7
08:12:00 08:20:00 8
20:50:00 20:50:00 0
20:51:00 20:51:00 0
20:52:00 20:52:00 0
3 3 2

//正常的测试例子,有vip和viptable
9
20:52:00 10 0
07:59:59 20 0
08:02:00 30 0
20:51:00 10 0
08:10:00 5 0
08:12:00 10 1
20:50:00 10 0
08:01:30 15 1
20:53:00 10 1
3 1
2
答案为:
07:59:59 08:00:00 0
08:01:30 08:01:30 0
08:02:00 08:02:00 0
08:12:00 08:16:30 5
08:10:00 08:20:00 10
20:50:00 20:50:00 0
20:51:00 20:51:00 0
20:52:00 20:52:00 0
3 3 2



//边缘测试例子
1
21:00:00 10 1
3 3
1 2 3

1
20:59:59 10 1
3 3
1 2 3

0
3 1
2

//vip桌子分配例子,有vip桌子时,优先把vip分到编号小的vip桌子,而不是编号小的vip桌子
4
06:00:00 30 1
08:00:00 30 1
10:00:00 30 1
12:00:00 30 1
5 1
3
答案为:
06:00:00 08:00:00 120
08:00:00 08:00:00 0
10:00:00 10:00:00 0
12:00:00 12:00:00 0
1 0 3 0 0

//超过两小时的例子
2
18:00:00 180 1
20:00:00 60 1
1 1
1
答案为:
18:00:00 18:00:00 0
20:00:00 20:00:00 0
2

//关于四舍五入为1分钟的例子,大约等于30秒才+1分钟,小于30则不+
3
07:59:31 60 1
07:59:29 60 1
08:00:30 100 1
2 1
1
答案为:
1
07:59:29 08:00:00 1
07:59:31 08:00:00 0
08:00:30 09:00:00 60
2 1
*/
string int2str(int a)
{
	char n = a / 10 + '0';
	char m = a % 10 + '0';
	string tmp = "";
	tmp += n;
	tmp += m;
	return tmp;

}
int char2int(char a)
{
	int tmp = a - '0';
	return tmp;
}
int time2int(string a)
{
	int hour = char2int(a[0]) * 10 + char2int(a[1]) - 8;
	int min = char2int(a[3]) * 10 + char2int(a[4]);
	int sec = char2int(a[6]) * 10 + char2int(a[7]);
	return hour * 3600 + min * 60 + sec;
}
struct playerNode{
	string arrive;
	int playTime, waitTime, serve;
	bool isVip;
	string serveStr();
	int waitInt();
	int serveTableNum;
	playerNode() :arrive(""), serve(maxServe), playTime(0), waitTime(0), isVip(false){};
	playerNode(string a, int p, bool v) :arrive(a), serve(maxServe), playTime(p), waitTime(0), isVip(v){};
};
string playerNode::serveStr()
{
	int hour = serve / 3600;
	int min = (serve - hour * 3600) / 60;
	int sec = serve % 60;
	return int2str(hour + 8) + ":" + int2str(min) + ":" + int2str(sec);
}
int playerNode::waitInt()
{
	int diff = serve - time2int(arrive);
	int min = diff / 60;
	if (diff % 60 >= 30)
		min++;
	return min;
}
struct tableNode{
	bool isVip;
	int playIndex;//当前玩家index
	int serveNum;//已经服务的玩家数量

	tableNode() :isVip(false), playIndex(-1), serveNum(0) {};
};
bool cmp(const playerNode&a, const playerNode&b)
{
	return a.arrive < b.arrive;
}
bool cmp2(const playerNode&a, const playerNode&b)
{//按照服务时间排序
	return a.serve < b.serve;
}
int main(void)
{
	int playerNum;
	cin >> playerNum;
	vector<playerNode> player(playerNum);
	vector<int> vipPlayer(0);
	for (int i = 0; i < playerNum; i++)
	{//输入玩家信息
		string arrive;
		int playTime;
		bool isVip;
		cin >> arrive >> playTime >> isVip;
		if (playTime > 120)
			playTime = 120;
		playTime *= 60;
		player[i].arrive = arrive;
		player[i].playTime = playTime;
		player[i].isVip = isVip;
	}
	sort(player.begin(), player.end(), cmp);

	for (int i = 0; i < playerNum; i++)
	{//建立vip队列
		if (player[i].isVip) vipPlayer.push_back(i);
	}

	int tableNum;
	int vipTableNum;
	cin >> tableNum >> vipTableNum;
	vector<tableNode> table(tableNum);
	vector<int> vipTable(0);
	int vipIndex = 0;
	int playerIndex = 0;
	for (int i = 0; i < vipTableNum; i++)
	{//输入vip桌子
		int a;
		cin >> a;
		table[a - 1].isVip = true;
		vipTable.push_back(a - 1);
	}

	for (int now = 0; now < 13 * 3600; now++)
	{
		for (int i = 0; i < table.size(); i++)
		{//遍历所有桌子,处理正在玩的玩家
			if (table[i].playIndex != -1)
			{//桌子有人
				player[table[i].playIndex].playTime--;
				if (player[table[i].playIndex].playTime <= 0)
				{//清空桌子
					table[i].playIndex = -1;
				}
			}
		}
		if (vipIndex < vipPlayer.size())
		{//先服务vip玩家
			for (int j = 0; j < vipTable.size(); j++)
			{
				while (vipIndex < vipPlayer.size() && player[vipPlayer[vipIndex]].serve != maxServe)
				{//跳过已经被服务的vip玩家,主要卡在这里
					vipIndex++;
				}
				int i = vipTable[j];//用i表示vip桌子
				if (table[i].playIndex == -1 && vipIndex < vipPlayer.size() && time2int(player[vipPlayer[vipIndex]].arrive) <= now)
				{
					table[i].serveNum++;
					table[i].playIndex = vipPlayer[vipIndex];
					player[vipPlayer[vipIndex]].serveTableNum = i;
					player[vipPlayer[vipIndex]].serve = now;
					vipIndex++;

				}
			}
		}

		if (playerIndex < player.size())
		{//服务剩下的玩家,普通玩家和vip玩家混在一起
			for (int i = 0; i < table.size(); i++)
			{
				while (playerIndex < player.size() && player[playerIndex].serve != maxServe)
				{//确保当前playerIndex的玩家是没有被服务的
					playerIndex++;
				}
				if (table[i].playIndex == -1 && playerIndex < player.size() && time2int(player[playerIndex].arrive) <= now)
				{
					table[i].serveNum++;
					table[i].playIndex = playerIndex;
					player[playerIndex].serveTableNum = i;
					player[playerIndex].serve = now;
					playerIndex++;
				}
			}
		}
	}

	sort(player.begin(), player.end(), cmp2);
	for (int i = 0; i < player.size(); i++)
	{
		if (player[i].serve != maxServe)
		{
			cout << player[i].arrive << " " << player[i].serveStr() << " " << player[i].waitInt() /*<<  " " << player[i].serveTableNum*/ << endl;
		}
	}
	for (int i = 0; i < table.size(); i++)
	{
		cout << table[i].serveNum;
		if (i != table.size() - 1)
			cout << " ";
	}


	return 0;
}

1025. PAT Ranking (25)

1.题目给出各个区域的用户分数,求出最终的区域排名和总排名。

2.用string记录ID。

3.熟悉sort函数的用法,选取合适的范围排序。

4.题目要求:相同分数的排名相同,分数相同的情况下ID需要按照递增排列。

5.处理排名,相同分数的学生,排名相同。如100,90,90,80,排名为1,2,2,4。

时间限制
200 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

Programming Ability Test (PAT) is organized by the College of Computer Science and Technology of Zhejiang University. Each test is supposed to run simultaneously in several places, and the ranklists will be merged immediately after the test. Now it is your job to write a program to correctly merge all the ranklists and generate the final rank.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive number N (<=100), the number of test locations. Then N ranklists follow, each starts with a line containing a positive integer K (<=300), the number of testees, and then K lines containing the registration number (a 13-digit number) and the total score of each testee. All the numbers in a line are separated by a space.

Output Specification:

For each test case, first print in one line the total number of testees. Then print the final ranklist in the following format:

registration_number final_rank location_number local_rank

The locations are numbered from 1 to N. The output must be sorted in nondecreasing order of the final ranks. The testees with the same score must have the same rank, and the output must be sorted in nondecreasing order of their registration numbers.

Sample Input:

2
5
1234567890001 95
1234567890005 100
1234567890003 95
1234567890002 77
1234567890004 85
4
1234567890013 65
1234567890011 25
1234567890014 100
1234567890012 85

Sample Output:

9
1234567890005 1 1 1
1234567890014 1 2 1
1234567890001 3 1 2
1234567890003 3 1 2
1234567890004 5 1 4
1234567890012 5 2 2
1234567890002 7 1 5
1234567890013 8 2 3
1234567890011 9 2 4
//#include<string>
//#include <iomanip>
#include<vector>
#include <algorithm>
//#include<stack>
#include<set>
#include<queue>
#include<map>
//#include<unordered_set>
//#include<unordered_map>
//#include <sstream>
//#include "func.h"
//#include <list>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
using namespace std;
/*
2
5
1234567890001 95
1234567890005 100
1234567890003 95
1234567890002 77
1234567890004 85
4
1234567890013 65
1234567890011 25
1234567890014 100
1234567890012 85

2
5
1234567890001 95
1234567890005 100
1234567890003 95
1234567890002 77
1234567890004 85
1
1234567890013 65

2
5
1234567890005 100
1234567890003 95
0000567890001 95
1234567890002 77
1234567890004 85
0

*/
struct studentNode{
	string id;
	int location, finalRank, localRank,score;
	studentNode() :id(""), location(-1), finalRank(-1), localRank(-1),score(-1){};
	studentNode(string i, int s) :id(i), location(-1), finalRank(-1), localRank(-1), score(s){};
};
bool cmp(const studentNode& a, const studentNode&b)
{
	if (a.score > b.score)
		return true;
	else if (a.score == b.score&&a.id < b.id)//分数相等的,ID按照递增排列
		return true;
	else return false;
}
int main(void)
{
	vector<studentNode> student(0);
	int locationNum, studentNum = 0;
	cin >> locationNum;//输入排名表的个数
	for (int location = 0; location < locationNum; location++)
	{
		int testNum; cin >> testNum;//输入每个排名表的学生数量
		if (testNum > 0)
		{
			for (int i = 0; i < testNum; i++)
			{
				string id; int score;
				cin >> id >> score;
				student.push_back(studentNode(id, score));
				student.back().location = location + 1;
				studentNum++;
			}

			//对排名表区域内的学生进行排序
			sort(student.begin() + studentNum - testNum, student.begin() + studentNum, cmp);
			student[studentNum - testNum].localRank = 1;
			for (int i = studentNum - testNum + 1; i < studentNum; i++)
			{//处理排名,相同分数的学生,排名相同。如100,90,90,80,排名为1,2,2,4
				if (student[i].score == student[i - 1].score)
					student[i].localRank = student[i - 1].localRank;
				else
					student[i].localRank = i - (studentNum - testNum ) + 1;
			}
		}
	}
	if (studentNum > 0)
	{//如果学生数量大于0,进行排序和统计排名
		sort(student.begin(), student.end(), cmp);
		student[0].finalRank = 1;
		for (int i = 1; i < studentNum; i++)
		{
			if (student[i].score == student[i - 1].score)
				student[i].finalRank = student[i - 1].finalRank;
			else
				student[i].finalRank = i + 1;
		}
	}
	cout << studentNum << endl;
	for (int i = 0; i < studentNum; i++)
	{
		cout << student[i].id << " " << student[i].finalRank << " " << student[i].location << " " << student[i].localRank << endl;
	}
	return 0;
}

1024. Palindromic Number (25)

1.判断一个数字与其位数翻转后相加是否回文,需要在限定的步数之内。

2.使用string存储数字。

3.用朴素的方法检测回。

4.需要考虑进位,和首位为0的情况(字符串翻转相加,为了避免长度不等,不需要去掉前面的‘0’)。

时间限制
400 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

A number that will be the same when it is written forwards or backwards is known as a Palindromic Number. For example, 1234321 is a palindromic number. All single digit numbers are palindromic numbers.

Non-palindromic numbers can be paired with palindromic ones via a series of operations. First, the non-palindromic number is reversed and the result is added to the original number. If the result is not a palindromic number, this is repeated until it gives a palindromic number. For example, if we start from 67, we can obtain a palindromic number in 2 steps: 67 + 76 = 143, and 143 + 341 = 484.

Given any positive integer N, you are supposed to find its paired palindromic number and the number of steps taken to find it.

Input Specification:

Each input file contains one test case. Each case consists of two positive numbers N and K, where N (<= 1010) is the initial numer and K (<= 100) is the maximum number of steps. The numbers are separated by a space.

Output Specification:

For each test case, output two numbers, one in each line. The first number is the paired palindromic number of N, and the second number is the number of steps taken to find the palindromic number. If the palindromic number is not found after K steps, just output the number obtained at the Kth step and K instead.

Sample Input 1:

67 3

Sample Output 1:

484
2

Sample Input 2:

69 3

Sample Output 2:

1353
3
//#include<string>
//#include <iomanip>
#include<vector>
#include <algorithm>
//#include<stack>
#include<set>
#include<queue>
#include<map>
//#include<unordered_set>
//#include<unordered_map>
//#include <sstream>
//#include "func.h"
//#include <list>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
using namespace std;

bool isPalindromic(string s)
{
	for (int i = 0; i < s.size() / 2; i++)
	{
		if (s[i] != s[s.size() - 1 - i])
			return false;
	}
	return true;
}
//string reverse(string s)
//{
//	string t = "";
//	int i = 0;
//	for (; i < s.size(); i++)
//	{//去掉开头的0
//		if (s[i] != '0') break;
//	}
//
//	for (; i < s.size(); i++)
//	{
//		t += s[i];
//	}
//	return t;
//}

int main(void)
{
	string s;//以string保存数字
	int k;
	cin >> s >> k;
	int step = 0;
	string t = s;
	while (step < k&&!isPalindromic(t))
	{
		s = t;
		t = "";
		for (int i = 0; i < s.size(); i++)
		{//t为s的翻转
			t = s[i] + t;
		}

		int carry = 0;
		string tmp = "";
		for (int i = s.size() - 1; i >= 0; i--)
		{//进行累加
			int digit = (s[i] - '0') + (t[i] - '0') + carry;
			carry = digit / 10;
			char c = digit % 10 + '0';
			tmp = c + tmp;
		}
		if (carry != 0)
		{//如果有进位,则需要添加
			char c = carry + '0';
			tmp = c + tmp;
		}
		int i = 0;
		for (; i < tmp.size(); i++)
		{//去掉前面的0
			if (tmp[i] != '0') break;
		}
		t = "";
		for (; i < tmp.size(); i++)
			t += tmp[i];//生成最终结果
		step++;
	}
	cout << t << endl << step << endl;

	return 0;
}

1023. Have Fun with Numbers (20)

1.题目要求给出一个数n,把这个数n乘以2后,判断2n与n是否只是不同的排列(没有多出新的数字)。

2.20位的数字,超过了unsigned long long的取值。

3.采用string进行存储和检测。

4.用哈希进行相同位检测。

时间限制
400 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

Notice that the number 123456789 is a 9-digit number consisting exactly the numbers from 1 to 9, with no duplication. Double it we will obtain 246913578, which happens to be another 9-digit number consisting exactly the numbers from 1 to 9, only in a different permutation. Check to see the result if we double it again!

Now you are suppose to check if there are more numbers with this property. That is, double a given number with k digits, you are to tell if the resulting number consists of only a permutation of the digits in the original number.

Input Specification:

Each input file contains one test case. Each case contains one positive integer with no more than 20 digits.

Output Specification:

For each test case, first print in a line “Yes” if doubling the input number gives a number that consists of only a permutation of the digits in the original number, or “No” if not. Then in the next line, print the doubled number.

Sample Input:

1234567899

Sample Output:

Yes
2469135798

 

//#include<string>
//#include <iomanip>
#include<vector>
#include <algorithm>
//#include<stack>
#include<set>
#include<queue>
#include<map>
//#include<unordered_set>
//#include<unordered_map>
//#include <sstream>
//#include "func.h"
//#include <list>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
using namespace std;
/*
3
0011111
The Testing Book
Yue Chen
test code debug sort keywords

2011
3333333
Another Testing Book
Yue Chen
test code sort keywords
ZUCS Print2
2012
2222222
The Testing Book
CYLL
keywords debug book
ZUCS Print2
2011
6
1: The Testing Book
2: Yue Chen
3: keywords
4:
5: 2011
3: blablabla

*/
int str2int(string s)
{
	int a = 0;
	for (int i = 0; i < s.size(); i++)
	{
		a = s[i] - '0' + a * 10;
	}
	return a;
}
int main(void)
{
	string s;
	cin >> s;//采用string记录数字
	string t = "";
	int carry = 0;
	bool ans = true;
	for (int i = s.size() - 1; i >= 0; i--)
	{//对数字乘以2,计算出一个新的string
		int digit = (s[i] - '0') * 2 + carry;
		carry = digit / 10;
		char c = digit % 10 + '0';
		t = c + t;
	}
	if (carry != 0)
	{//判断最后有没有进位
		ans = false;
		char c = carry + '0';
		t = c + t;
	}
	if (ans)
	{
		int digit[10] = { 0 };
		for (int i = 0; i < s.size(); i++)
		{//判断各个数出现的次数
			digit[s[i] - '0']++;
			digit[t[i] - '0']--;
		}
		for (int i = 0; i < 10; i++)
		{//如果s和t的数字出现次数不等,则不合要求
			if (digit[i] != 0) ans = false;
		}
	}
	if (ans) cout << "Yes" << endl;
	else cout << "No" << endl;
	cout << t << endl;
	return 0;
}

1022. Digital Library (30)

1.题目给出一些书本的信息,根据查询的信息,输出书的ID

2.采用map<string, set<string>> 的结构进行存储,可利用string自身带有的排序进行排序。

3.如果采用map<string, set<int>> ,输出的时候则需要考虑ID为0001111的,前面带有0的情况(主要卡在这里)。

时间限制
1000 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

A Digital Library contains millions of books, stored according to their titles, authors, key words of their abstracts, publishers, and published years. Each book is assigned an unique 7-digit number as its ID. Given any query from a reader, you are supposed to output the resulting books, sorted in increasing order of their ID’s.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<=10000) which is the total number of books. Then N blocks follow, each contains the information of a book in 6 lines:

  • Line #1: the 7-digit ID number;
  • Line #2: the book title — a string of no more than 80 characters;
  • Line #3: the author — a string of no more than 80 characters;
  • Line #4: the key words — each word is a string of no more than 10 characters without any white space, and the keywords are separated by exactly one space;
  • Line #5: the publisher — a string of no more than 80 characters;
  • Line #6: the published year — a 4-digit number which is in the range [1000, 3000].

It is assumed that each book belongs to one author only, and contains no more than 5 key words; there are no more than 1000 distinct key words in total; and there are no more than 1000 distinct publishers.

After the book information, there is a line containing a positive integer M (<=1000) which is the number of user’s search queries. Then M lines follow, each in one of the formats shown below:

  • 1: a book title
  • 2: name of an author
  • 3: a key word
  • 4: name of a publisher
  • 5: a 4-digit number representing the year

Output Specification:

For each query, first print the original query in a line, then output the resulting book ID’s in increasing order, each occupying a line. If no book is found, print “Not Found” instead.

Sample Input:

3
1111111
The Testing Book
Yue Chen
test code debug sort keywords
ZUCS Print
2011
3333333
Another Testing Book
Yue Chen
test code sort keywords
ZUCS Print2
2012
2222222
The Testing Book
CYLL
keywords debug book
ZUCS Print2
2011
6
1: The Testing Book
2: Yue Chen
3: keywords
4: ZUCS Print
5: 2011
3: blablabla

Sample Output:

1: The Testing Book
1111111
2222222
2: Yue Chen
1111111
3333333
3: keywords
1111111
2222222
3333333
4: ZUCS Print
1111111
5: 2011
1111111
2222222
3: blablabla
Not Found
//#include<string>
//#include <iomanip>
#include<vector>
#include <algorithm>
//#include<stack>
#include<set>
#include<queue>
#include<map>
//#include<unordered_set>
//#include<unordered_map>
//#include <sstream>
//#include "func.h"
//#include <list>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
using namespace std;
/*
3
0011111
The Testing Book
Yue Chen
test code debug sort keywords

2011
3333333
Another Testing Book
Yue Chen
test code sort keywords
ZUCS Print2
2012
2222222
The Testing Book
CYLL
keywords debug book
ZUCS Print2
2011
6
1: The Testing Book
2: Yue Chen
3: keywords
4:
5: 2011
3: blablabla

*/
int str2int(string s)
{
	int a = 0;
	for (int i = 0; i < s.size(); i++)
	{
		a = s[i] - '0' + a * 10;
	}
	return a;
}
int main(void)
{
	string bookNumStr;
	getline(cin, bookNumStr);
	int bookNum;
	bookNum = str2int(bookNumStr);
	//最终查询输出的是ID,所以针对每个查询的词条,都建立一个ID集合
	//使用set存储ID,直接进行了排序
	map<string, set<string>> keyWord;//1000*80B+5*10000*7B=80K+350K=430K
	map<string, set<string>> publisher;//1000*80B+10000*7B=80K+70K=150K
	map<string, set<string>> year;//2000*4B+10000*7B=8K+70K=78K
	map<string, set<string>> author;//10000*80B+10000*7B=800K+70K=870K
	map<string, set<string>> title;//10000*80B+10000*7B=800K+70K=870K

	for (int i = 0; i < bookNum; i++)
	{
		string ID;
		string IDstr, titleTemp, authorTemp, keyWordTemp, publishedTemp, yearTemp;
		getline(cin, IDstr, '\n');

		getline(cin, titleTemp, '\n');
		getline(cin, authorTemp, '\n');
		getline(cin, keyWordTemp, '\n');
		getline(cin, publishedTemp, '\n');
		getline(cin, yearTemp, '\n');

		//ID = str2int(IDstr);
		ID = IDstr;

		int start = 0;
		for (int j = 0; j < keyWordTemp.size(); j++)
		{
			if (keyWordTemp[j] == ' ')
			{
				string temp = keyWordTemp.substr(start, j - start);
				start = j + 1;//跳过空格
				keyWord[temp].insert(ID);
			}
		}
		if (keyWordTemp.substr(start) != "")
			keyWord[keyWordTemp.substr(start)].insert(ID);
		if (titleTemp != "")
			title[titleTemp].insert(ID);
		if (authorTemp != "")
			author[authorTemp].insert(ID);
		if (publishedTemp != "")
			publisher[publishedTemp].insert(ID);
		if (yearTemp != "")
			year[yearTemp].insert(ID);
	}
	string queryStr;
	getline(cin, queryStr, '\n');
	int query = str2int(queryStr);
	for (int i = 0; i < query; i++)
	{
		string s;
		getline(cin, s, '\n');
		string outStr = s;
		int num;
		num = s[0] - '0';
		s = s.substr(3);
		cout << outStr << endl;
		if (num == 1 && title.find(s) != title.end())
		{//查询的是title
			for (set<string>::iterator ite = title[s].begin(); ite != title[s].end(); ite++)
				cout << *ite << endl;
		}
		else if (num == 2 && author.find(s) != author.end())
		{//查询的是作者
			for (set<string>::iterator ite = author[s].begin(); ite != author[s].end(); ite++)
				cout << *ite << endl;
		}
		else if (num == 3 && keyWord.find(s) != keyWord.end())
		{//查询的是关键词
			for (set<string>::iterator ite = keyWord[s].begin(); ite != keyWord[s].end(); ite++)
				cout << *ite << endl;
		}
		else if (num == 4 && publisher.find(s) != publisher.end())
		{//查询的是出版商
			for (set<string>::iterator ite = publisher[s].begin(); ite != publisher[s].end(); ite++)
				cout << *ite << endl;
		}
		else if (num == 5 && year.find(s) != year.end())
		{//查询的是年份
			for (set<string>::iterator ite = year[s].begin(); ite != year[s].end(); ite++)
				cout << *ite << endl;
		}
		else
		{//没有找到对应结果
			cout << "Not Found" << endl;
		}
	}
	return 0;
}

1021. Deepest Root (25)

1.题目要求求一个图,以哪个节点作为根生成的树高度最高,不唯一则按照从小到大输出;如果图不是一个连通图,则输出有多少个分支。

2.采用并查集来检测是否存在2个或2个以上集合。

3.使用广度优先搜索进行求多源路径。

4.使用Floyd算法会超出内存(可计算10000*10000的int的大小),使用DFS会出现栈溢出(10000深度太深了)。

 

时间限制
1500 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

A graph which is connected and acyclic can be considered a tree. The height of the tree depends on the selected root. Now you are supposed to find the root that results in a highest tree. Such a root is called the deepest root.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<=10000) which is the number of nodes, and hence the nodes are numbered from 1 to N. Then N-1 lines follow, each describes an edge by given the two adjacent nodes’ numbers.

Output Specification:

For each test case, print each of the deepest roots in a line. If such a root is not unique, print them in increasing order of their numbers. In case that the given graph is not a tree, print “Error: K components” where K is the number of connected components in the graph.

Sample Input 1:

5
1 2
1 3
1 4
2 5

Sample Output 1:

3
4
5

Sample Input 2:

5
1 3
1 4
2 5
3 4

Sample Output 2:

Error: 2 components

 

//#include<string>
//#include <iomanip>
#include<vector>
#include <algorithm>
//#include<stack>
#include<set>
#include<queue>
#include<map>
//#include<unordered_set>
//#include<unordered_map>
//#include <sstream>
//#include "func.h"
//#include <list>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
using namespace std;
class VertexNode{
public:
	vector<int> list;
	VertexNode() :list(0){};
};
int findRepresent(int a, int* r)
{
	if (r[a] == a)
		return a;
	else
	{
		r[a] = findRepresent(r[a], r);
		return r[a];
	}
}
void dfs(int&node, VertexNode *v, int &maxDeep, int deep, int&root, bool*used, vector<pair<int, int>>&ans)
{
	bool visitedAll = true;
	for (int i = 0; i < v[node].list.size(); i++)
	{
		int p = v[node].list[i];
		if (!used[p])
		{
			used[p] = true;
			visitedAll = false;
			dfs(p, v, maxDeep, deep + 1, root, used, ans);
			used[p] = false;
		}
	}
	if (visitedAll&&deep >= maxDeep)
	{
		maxDeep = deep;
		ans.push_back({ root, deep });
	}
}
bool cmp(const pair<int, int>&a, const pair<int, int>&b)
{
	if (a.second>b.second)
		return true;
	else if (a.second == b.second && a.first < b.first)
		return true;
	else
		return false;
}
int main(void)
{
	int nodeNum;
	cin >> nodeNum;
	//VertexNode *v = new VertexNode[nodeNum];//节点
	vector<VertexNode> v(nodeNum);
	vector<int> temp(0);
	for (int i = 0; i < nodeNum - 1; i++)
	{
		v[i].list = temp;
	}
	int *r = new int[nodeNum];//代表
	for (int i = 0; i < nodeNum; i++)
		r[i] = i;
	for (int i = 0; i < nodeNum - 1; i++)
	{
		int a, b;
		cin >> a >> b; a--; b--;
		v[a].list.push_back(b);
		v[b].list.push_back(a);
		r[findRepresent(a, r)] = findRepresent(b, r);//合并a和b
	}
	int setNum = 0;
	for (int i = 0; i < nodeNum; i++)
	{//并查集检测集合数量
		if (i == r[i]) setNum++;
	}
	delete[]r;
	if (setNum >= 2)
	{
		printf("Error: %d components\n", setNum);
		return 0;
	}

	/*bool *used = new bool[nodeNum];
	memset(used, false, sizeof(used));*/
	vector<bool> used (nodeNum, false);
	vector<pair<int, int>> ans(0);
	int maxDeep = 0;

	for (int root = 0; root < nodeNum; root++)
	{//对每一个点使用广度优先搜索,BFS
		//memset(used, false, sizeof(used));

		vector<bool> used = vector<bool>(nodeNum, false);
		queue<int>q;
		q.push(root);
		int total = 1;
		int total2 = 0;
		int deep = 0;
		used[root] = true;
		//cout << "root:" << root << endl;
		while (!q.empty())
		{
			deep++;
			//cout << "layer" << deep << " :";
			for (int i = 0; i < total; ++i)
			{
				int top = q.front(); q.pop();
				for (int j = 0; j < v[top].list.size(); ++j)
				{
					int p = v[top].list[j];
					if (!used[p])
					{
						//cout << p << " ";
						used[p] = true;
						q.push(p);
						total2++;
					}
				}
			}
			total = total2;
			total2 = 0;
			//cout << endl;
		}
		//cout << endl;
		if (deep >= maxDeep)
		{
			maxDeep = deep;
			ans.push_back({ root, deep });
		}
	}

	sort(ans.begin(), ans.end(), cmp);
	for (int i = 0; i < nodeNum; i++)
	{
		used[i] = false;
	}
	for (int i = 0; i < ans.size(); i++)
	{
		if (ans[i].second == maxDeep)
		{
			used[ans[i].first] = true;
			//cout << ans[i].first << endl;
		}
		else break;
	}
	for (int i = 0; i < nodeNum; i++)
	{
		if (used[i])
			cout << i + 1 << endl;
	}
	return 0;
}

1020. Tree Traversals (25)

1.题目要求按照后续和中序还原二叉树,然后进行层次遍历输出。

还原的函数为:

class TreeNode{
public:
	int val;
	TreeNode* l, *r;
	TreeNode(int x) :val(x), l(NULL), r(NULL){};
	TreeNode() :val(0), l(NULL), r(NULL){};
};
TreeNode* build(vector<int>&postOrder, int postStart, int postEnd,
	vector<int>&inOrder, int inStart, int inEnd, int&index, vector<TreeNode>&tree)
{
	if (postStart == postEnd)
	{//如果start和end相同,即这个是叶子节点
		tree[index++] = TreeNode(postOrder[postEnd]);
		return &tree[index - 1];
	}
	else if (postStart > postEnd) return NULL;
	else
	{
		int rootVal = postOrder[postEnd];//后序遍历的末位是根
		int rootPos = inStart;//根在中序遍历中的位置
		for (; rootPos <= inEnd; rootPos++)
		{
			if (rootVal == inOrder[rootPos])
				break;
		}
		int returnNode = index++;
		tree[returnNode] = TreeNode(rootVal);
		//注意newPostEnd = postStart + rootPos - inStart-1
		tree[returnNode].l = build(postOrder, postStart, postStart + rootPos - inStart-1, inOrder, inStart, rootPos - 1, index, tree);
		tree[returnNode].r = build(postOrder, postStart + rootPos - inStart , postEnd - 1, inOrder, rootPos + 1, inEnd, index, tree);
		return &tree[returnNode];

	}
}
时间限制
400 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder and inorder traversal sequences, you are supposed to output the level order traversal sequence of the corresponding binary tree.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (<=30), the total number of nodes in the binary tree. The second line gives the postorder sequence and the third line gives the inorder sequence. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in one line the level order traversal sequence of the corresponding binary tree. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the end of the line.

Sample Input:

7
2 3 1 5 7 6 4
1 2 3 4 5 6 7

Sample Output:

4 1 6 3 5 7 2

 
AC代码:

//#include<string>
//#include <iomanip>
#include<vector>
#include <algorithm>
//#include<stack>
#include<set>
#include<queue>
#include<map>
//#include<unordered_set>
//#include<unordered_map>
//#include <sstream>
//#include "func.h"
//#include <list>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
using namespace std;
class TreeNode{
public:
	int val;
	TreeNode* l, *r;
	TreeNode(int x) :val(x), l(NULL), r(NULL){};
	TreeNode() :val(0), l(NULL), r(NULL){};
};
TreeNode* build(vector<int>&postOrder, int postStart, int postEnd,
	vector<int>&inOrder, int inStart, int inEnd, int&index, vector<TreeNode>&tree)
{
	if (postStart == postEnd)
	{//如果start和end相同,即这个是叶子节点
		tree[index++] = TreeNode(postOrder[postEnd]);
		return &tree[index - 1];
	}
	else if (postStart > postEnd) return NULL;
	else
	{
		int rootVal = postOrder[postEnd];//后序遍历的末位是根
		int rootPos = inStart;//根在中序遍历中的位置
		for (; rootPos <= inEnd; rootPos++)
		{
			if (rootVal == inOrder[rootPos])
				break;
		}
		int returnNode = index++;
		tree[returnNode] = TreeNode(rootVal);
		//注意newPostEnd = postStart + rootPos - inStart-1
		tree[returnNode].l = build(postOrder, postStart, postStart + rootPos - inStart-1, inOrder, inStart, rootPos - 1, index, tree);
		tree[returnNode].r = build(postOrder, postStart + rootPos - inStart , postEnd - 1, inOrder, rootPos + 1, inEnd, index, tree);
		return &tree[returnNode];

	}
}
int main(void)
{
	int nodeNum;
	cin >> nodeNum;
	vector<int> postOrder(nodeNum, 0);//后序
	vector<int> inOrder(nodeNum, 0);//中序

	for (int i = 0; i < nodeNum; i++)
	{
		cin >> postOrder[i];
	}
	for (int i = 0; i < nodeNum; i++)
	{
		cin >> inOrder[i];
	}
	vector<TreeNode> tree(nodeNum);//提前分配后内存空间,方便后面的连接
	int index=0;
	TreeNode*ans = build(postOrder, 0, nodeNum - 1, inOrder, 0, nodeNum - 1, index, tree);

	int total = 0;
	int total2 = 0;
	queue<TreeNode*> q;
	if (ans != NULL)
	{
		total = 1;
		q.push(ans);
	}
	vector<int> outNum(0);
	while (!q.empty())
	{//进行BFS
		while (total--)
		{
			TreeNode* front = q.front(); q.pop();
			outNum.push_back(front->val);
			if (front->l!=NULL)
			{
				q.push(front->l);
				total2++;
			}
			if (front->r != NULL)
			{
				q.push(front->r);
				total2++;
			}

		}
		total = total2;
		total2 = 0;
	}
	for (int i = 0; i < outNum.size(); i++)
	{
		cout << outNum[i];
		if (i != outNum.size() - 1)
			cout << " ";
	}

	return 0;
}

1019. General Palindromic Number (20)

1.题目要求,求一个数N在B进制表示的情况下,是否构成回文。

2.采用求余的方式转换成以radix为基数的数

3.使用vector<int>来存储底数,因为后面需要以底数的形式显示,而不是以位的形式显示

print N as the number in base b in the form “ak ak-1 … a0“.

4.注意输入为0的情况

时间限制
400 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

A number that will be the same when it is written forwards or backwards is known as a Palindromic Number. For example, 1234321 is a palindromic number. All single digit numbers are palindromic numbers.

Although palindromic numbers are most often considered in the decimal system, the concept of palindromicity can be applied to the natural numbers in any numeral system. Consider a number N > 0 in base b >= 2, where it is written in standard notation with k+1 digits ai as the sum of (aibi) for i from 0 to k. Here, as usual, 0 <= ai < b for all i and ak is non-zero. Then N is palindromic if and only if ai = ak-i for all i. Zero is written 0 in any base and is also palindromic by definition.

Given any non-negative decimal integer N and a base b, you are supposed to tell if N is a palindromic number in base b.

Input Specification:

Each input file contains one test case. Each case consists of two non-negative numbers N and b, where 0 <= N <= 109 is the decimal number and 2 <= b <= 109 is the base. The numbers are separated by a space.

Output Specification:

For each test case, first print in one line “Yes” if N is a palindromic number in base b, or “No” if not. Then in the next line, print N as the number in base b in the form “ak ak-1 … a0“. Notice that there must be no extra space at the end of output.

Sample Input 1:

27 2

Sample Output 1:

Yes
1 1 0 1 1

Sample Input 2:

121 5

Sample Output 2:

No
4 4 1

AC代码:

//#include<string>
//#include <iomanip>
#include<vector>
#include <algorithm>
//#include<stack>
#include<set>
#include<queue>
#include<map>
//#include<unordered_set>
//#include<unordered_map>
//#include <sstream>
//#include "func.h"
//#include <list>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
using namespace std;
int main(void)
{
	long long number, radix;
	cin >> number >> radix;
	vector<int> base(0);
	if (number == 0) base.push_back(0);
	while (number != 0)
	{
		//余数很有可能超过char的范围,例如999%1000=999
		base.push_back(number%radix);
		number /= radix;
	}
	bool ans = true;
	for (int i = 0; i < base.size() / 2; i++)
	{
		if (ans && base[i] != base[base.size() - 1 - i])//判断回文
			ans = false;
		swap(base[i], base[base.size() - 1 - i]);//求出来的底数是倒序的,顺便把顺序调整过来
	}
	if (ans)
		cout << "Yes" << endl;
	else
		cout << "No" << endl;
	for (int i = 0; i < base.size(); i++)
	{
		cout << base[i];
		if (i != base.size() - 1)
			cout << " ";
	}
	cout << endl;

	return 0;
}

1018. Public Bike Management (30)

1.题目给出一个缺单车的站点,要求求出最小耗费路径,如果最小耗费路径不唯一,需要进行下面的处理。

2.采用dijkstra计算出最小耗费cost,再用最小耗费cost作为约束条件,进行遍历。

3.关键在于后面如何选择最优的路径,选择需要发送最小数量的路径,如果两者发送的数量相同,则选择take数量最小的路径。

4.如0->2->3->4->5, 节点2缺单车,需要send,而节点3单车多出来,只能够补充4或者5的单车,不能反过来补充节点2的单车。

时间限制
400 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

There is a public bike service in Hangzhou City which provides great convenience to the tourists from all over the world. One may rent a bike at any station and return it to any other stations in the city.

The Public Bike Management Center (PBMC) keeps monitoring the real-time capacity of all the stations. A station is said to be in perfect condition if it is exactly half-full. If a station is full or empty, PBMC will collect or send bikes to adjust the condition of that station to perfect. And more, all the stations on the way will be adjusted as well.

When a problem station is reported, PBMC will always choose the shortest path to reach that station. If there are more than one shortest path, the one that requires the least number of bikes sent from PBMC will be chosen.

pat1018
Figure 1
Figure 1 illustrates an example. The stations are represented by vertices and the roads correspond to the edges. The number on an edge is the time taken to reach one end station from another. The number written inside a vertex S is the current number of bikes stored at S. Given that the maximum capacity of each station is 10. To solve the problem at S3, we have 2 different shortest paths:

1. PBMC -> S1 -> S3. In this case, 4 bikes must be sent from PBMC, because we can collect 1 bike from S1 and then take 5 bikes to S3, so that both stations will be in perfect conditions.

2. PBMC -> S2 -> S3. This path requires the same time as path 1, but only 3 bikes sent from PBMC and hence is the one that will be chosen.

Input Specification:

Each input file contains one test case. For each case, the first line contains 4 numbers: Cmax (<= 100), always an even number, is the maximum capacity of each station; N (<= 500), the total number of stations; Sp, the index of the problem station (the stations are numbered from 1 to N, and PBMC is represented by the vertex 0); and M, the number of roads. The second line contains N non-negative numbers Ci (i=1,…N) where each Ci is the current number of bikes at Si respectively. Then M lines follow, each contains 3 numbers: Si, Sj, and Tij which describe the time Tij taken to move betwen stations Si and Sj. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print your results in one line. First output the number of bikes that PBMC must send. Then after one space, output the path in the format: 0->S1->…->Sp. Finally after another space, output the number of bikes that we must take back to PBMC after the condition of Sp is adjusted to perfect.

Note that if such a path is not unique, output the one that requires minimum number of bikes that we must take back to PBMC. The judge’s data guarantee that such a path is unique.

Sample Input:

10 3 3 5
6 7 0
0 1 1
0 2 1
0 3 3
1 3 1
2 3 1

Sample Output:

3 0->2->3 0

AC代码:

//
//  main.cpp
//  the beauty of programming
//
//  Created by siukwan on 15/08/26.
//  Copyright (c) 2015年 siukwan. All rights reserved.
//

#include <iostream>
#include <stdio.h>
#include <vector>
#include <stack>
#include <algorithm>
#include <memory.h>
#include "limits.h"
using namespace std;

class vertexNode{
public:
    vector<int> list;
    bool visited, sured;
    long long cost;
    int cap;
    vertexNode() :list(0), visited(false), sured(false), cost(INT_MAX), cap(0){};
};

void dfs(vector<bool> & used,int now,int target,
         long long nowCost,long long &minCost,vector<vector<int>>&ans,vector<int>&path,vector<vertexNode>& v,
         vector<vector<long long>>&w )
{
    if (now == target&&nowCost == minCost)
    {
        ans.push_back(path);
    }
    else
    {
        for (int i = 0; i < v[now].list.size(); i++)
        {
            int p = v[now].list[i];
            if (!used[p] && nowCost + w[now][p] <= minCost)
            {
                used[p] = true;
                path.push_back(p);
                dfs(used, p, target, nowCost + w[now][p], minCost, ans, path, v, w);
                path.pop_back();
                used[p] = false;
            }
        }
    }
};

int main(void)
{
    int capMax, n, sp, m;
    cin >> capMax >> n >> sp >> m;
    n++;//PBMC记为0,接下来的城市为1~n,所以n++
    vector<vertexNode> v(n);
    for (int i = 1; i < n; i++)
    {
        cin >> v[i].cap;
    }
    vector<vector<long long> > w(n, vector<long long>(n, INT_MAX));
    for (int i = 0; i < m; i++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        if (w[a][b] > c)
        {
            w[a][b] = c;
            w[b][a] = c;
            v[a].list.push_back(b);
            v[b].list.push_back(a);
        }
    }
    
    v[0].visited = true;
    v[0].cap = 0;
    v[0].cost = 0;
    while (1)
    {
        int p = -1;
        for (int i = 0; i < n; i++)
        {//找出已经探索的最小耗费的点
            if (p == -1 && v[i].visited&&!v[i].sured)
                p = i;
            else if (p != -1 && v[i].visited&&!v[i].sured && v[p].cost > v[i].cost)
                p = i;
        }
        if (p == -1) break;
        v[p].sured = true;//确定p点
        if (v[sp].sured) break;//目标点的最短路径确认后,不再遍历
        for (int i = 0; i < v[p].list.size(); i++)
        {
            int q = v[p].list[i];
            if (!v[q].sured && v[p].cost + w[p][q] < v[q].cost)
            {//更新最短路径
                v[q].visited = true;
                v[q].cost = v[p].cost + w[p][q];
            }
        }
    }
    
    vector<bool> used(n, false);
    long long minCost = v[sp].cost;//最小耗费
    vector<vector<int>> ans(0, vector<int>(0));
    vector<int> path(0);
    dfs(used, 0, sp, 0, minCost, ans, path, v, w);
    int minSendBike=INT_MAX;
    int minCurBike=INT_MAX;
    int minIndex=-1;
    for (int i = 0; i < ans.size(); i++)
    {//遍历每个答案
        int sendBike = 0;
        int curBike = 0;
        int perfectCap = capMax/2;
        for (int j = 0; j < ans[i].size(); j++)
        {
            if(v[ans[i][j]].cap+curBike < perfectCap)
            {//如果当前单车总数加上节点的现有单车数都达不到完美容量,则需要send
                sendBike+=perfectCap-v[ans[i][j]].cap-curBike;
                curBike=0;
            }
            else
            {
                curBike=v[ans[i][j]].cap+curBike-perfectCap;
            }
        }
        if(minSendBike>sendBike)
        {//如果发送单车数量小于当前最小值,则更新
            minSendBike=sendBike;
            minIndex=i;
            minCurBike=curBike;
        }
        else if(minSendBike==sendBike && minCurBike>curBike)
        {//如果send的数量相同,则判断需要take的最小值,进行更新
            minSendBike=sendBike;
            minIndex=i;
            minCurBike=curBike;
        }
        
    }
    long long send;
    long long take;
    send=minSendBike;
    take=minCurBike;
    cout << send << " ";
    if (ans[minIndex].size() > 0)
    {
        cout << "0";
        for (int i = 0; i < ans[minIndex].size(); i++)
        {
            cout << "->"<< ans[minIndex][i] ;
        }
    }
    cout << " "<< take << endl;
    
    
    return 0;
}

1017. Queueing at Bank (25)

1.题目给出用户到达的时间和需要处理的时间,求出平均等到时间

2.在17:00:00前(包括17整)来的客户,都要确保一直执行完,即使超过了17点。譬如一个在8点来的客户,处理时间需要20小时,也需要同样服务完,然后处理队列中的客户。

3.只是对17:00:00后来的客户拒绝服务,用户在17:00:00前来,也需要放到队列中进行处理(和2的说法对应)。

4.逻辑顺序有问题,需要先插入,然后再减时间。

5.首次插入,需要判断时间是否合适。

6.直接对每一秒进行模拟,目前N=10000,K=100,对于N*K的复杂度,PAT能够接受,在400ms内。

QQ截图20151129190603

时间限制
400 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

Suppose a bank has K windows open for service. There is a yellow line in front of the windows which devides the waiting area into two parts. All the customers have to wait in line behind the yellow line, until it is his/her turn to be served and there is a window available. It is assumed that no window can be occupied by a single customer for more than 1 hour.

Now given the arriving time T and the processing time P of each customer, you are supposed to tell the average waiting time of all the customers.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 numbers: N (<=10000) – the total number of customers, and K (<=100) – the number of windows. Then N lines follow, each contains 2 times: HH:MM:SS – the arriving time, and P – the processing time in minutes of a customer. Here HH is in the range [00, 23], MM and SS are both in [00, 59]. It is assumed that no two customers arrives at the same time.

Notice that the bank opens from 08:00 to 17:00. Anyone arrives early will have to wait in line till 08:00, and anyone comes too late (at or after 17:00:01) will not be served nor counted into the average.

Output Specification:

For each test case, print in one line the average waiting time of all the customers, in minutes and accurate up to 1 decimal place.

Sample Input:

7 3
07:55:00 16
17:00:01 2
07:59:59 15
08:01:00 60
08:00:00 30
08:00:02 2
08:03:00 10

Sample Output:

8.2

 

AC代码:
/*
1.在17:00:00前(包括17整)来的客户,都要确保一直执行完,即使超过了17点
2.只是对17:00:00后来的客户拒绝服务
3.逻辑顺序有问题,需要先插入,然后再减时间
*/
//#include<string>
//#include <iomanip>
#include<vector>
#include <algorithm>
//#include<stack>
#include<set>
#include<queue>
#include<map>
//#include<unordered_set>
//#include<unordered_map>
//#include <sstream>
//#include "func.h"
//#include <list>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
using namespace std;
class customNode{
public:
	int process, start, arrivalSecond, waitTime;
	int calculateWaitTime();
	customNode() :process(-1), start(-1), arrivalSecond(-1), waitTime(-1){};
};
int time2int(string a)
{//string转化为00:00:00到现在的时间
	return ((a[0] - '0') * 10 + a[1] - '0') * 3600 + ((a[3] - '0') * 10 + a[4] - '0') * 60 + ((a[6] - '0') * 10 + a[7] - '0');
}
int customNode::calculateWaitTime()
{//计算等待时间
	return start - arrivalSecond;
}
bool cmp(const customNode&a, const customNode&b)
{
	return a.arrivalSecond < b.arrivalSecond;
}
int main(void)
{
	int n, k;
	cin >> n >> k;
	int startTime = 8 * 3600;//8点
	int endTime = 17 * 3600;//17点
	vector<customNode> custom(0);
	for (int i = 0; i < n; i++)
	{
		int hour, minute, second, process;
		scanf("%d:%d:%d %d", &hour, &minute, &second, &process);
		int arrivalTime = hour * 3600 + minute * 60 + second;
		if (arrivalTime <= endTime)
		{//小于17:00:00的才加入
			custom.push_back(customNode());
			custom.back().arrivalSecond = arrivalTime;
			custom.back().process = process * 60;
			custom.back().start = -1;
		}
	}
	sort(custom.begin(), custom.end(), cmp);
	n = custom.size();
	int query = 0;
	vector<int> window(k, -1);
	//while (query < n && query < k && custom[query].arrivalSecond <= startTime)
	//{//本来卡在了这里,插入时缺少判断时间是否合适
	//	window[query] = query;
	//	custom[query].start = startTime;//第一批到的人,记为0,即08:00:00开始处理
	//	query++;
	//}

	int now = startTime;
	for (int i = startTime; query < n; i++)
	{//注意结束条件是query>=n,即凡是压进队列的用户,都必须接受处理,17点后到来的用户已经不在队列中
		now = i;
		//先进行插入,遍历k个窗口
		for (int j = 0; j < k; j++)
		{

			if (window[j] == -1 && query < n)//窗口为空闲时
			{
				if (custom[query].arrivalSecond <= now)
				{//队列中还有客户,且客户的到达时间小于等于当前时间
					window[j] = query;
					custom[query].start = now;
					query++;
				}
			}
		}
		//进行减时间,如8点到的用户,现在刚好是8点,process为1分钟,那么process已经-1,为0了,所以即使空出来,也得等到8点01分才能插入(即等到下一个周期)
		for (int j = 0; j < k; j++)
		{//遍历k个窗口
			if (window[j] != -1)
			{
				int num = window[j];
				custom[num].process--;
				if (custom[num].process == 0)//当客户的处理时间为0时,代表结束
					window[j] = -1;//窗口置为空闲
			}
		}
	}

	int waitTime = 0;
	for (int i = 0; i < n; i++)
	{
		custom[i].waitTime = custom[i].calculateWaitTime();
		waitTime += custom[i].waitTime;
	}
	if (n == 0)
		printf("%.1f", 0.0);
	else
		printf("%.1f", waitTime / 60.0 / n);
	cout << endl;

	return 0;
}