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;
}

1016. Phone Bills (25)

1.题目要求把聊天记录分类匹配,然后输出相应的话费和记录。

2.判断记录好坏,把所有记录以string存起来,按照字典序排序,相邻的两条记录满足要求:第一条为on-line且第二条为off-line,才是成功匹配;

3.采用计算00:00:00到现在的耗费和分钟数,这个方法比较简单

4.最重要的:题目中只强调至少有一条匹配成功的记录,不是说每个人都至少有一条匹配成功的记录,所以没有成功匹配记录的人不输出(主要卡在这)

QQ截图20151129190603

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

A long-distance telephone company charges its customers by the following rules:

Making a long-distance call costs a certain amount per minute, depending on the time of day when the call is made. When a customer starts connecting a long-distance call, the time will be recorded, and so will be the time when the customer hangs up the phone. Every calendar month, a bill is sent to the customer for each minute called (at a rate determined by the time of day). Your job is to prepare the bills for each month, given a set of phone call records.

Input Specification:

Each input file contains one test case. Each case has two parts: the rate structure, and the phone call records.

The rate structure consists of a line with 24 non-negative integers denoting the toll (cents/minute) from 00:00 – 01:00, the toll from 01:00 – 02:00, and so on for each hour in the day.

The next line contains a positive number N (<= 1000), followed by N lines of records. Each phone call record consists of the name of the customer (string of up to 20 characters without space), the time and date (mm:dd:hh:mm), and the word “on-line” or “off-line”.

For each test case, all dates will be within a single month. Each “on-line” record is paired with the chronologically next record for the same customer provided it is an “off-line” record. Any “on-line” records that are not paired with an “off-line” record are ignored, as are “off-line” records not paired with an “on-line” record. It is guaranteed that at least one call is well paired in the input. You may assume that no two records for the same customer have the same time. Times are recorded using a 24-hour clock.

Output Specification:

For each test case, you must print a phone bill for each customer.

Bills must be printed in alphabetical order of customers’ names. For each customer, first print in a line the name of the customer and the month of the bill in the format shown by the sample. Then for each time period of a call, print in one line the beginning and ending time and date (dd:hh:mm), the lasting time (in minute) and the charge of the call. The calls must be listed in chronological order. Finally, print the total charge for the month in the format shown by the sample.

Sample Input:

10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10
10
CYLL 01:01:06:01 on-line
CYLL 01:28:16:05 off-line
CYJJ 01:01:07:00 off-line
CYLL 01:01:08:03 off-line
CYJJ 01:01:05:59 on-line
aaa 01:01:01:03 on-line
aaa 01:02:00:01 on-line
CYLL 01:28:15:41 on-line
aaa 01:05:02:24 on-line
aaa 01:04:23:59 off-line

Sample Output:

CYJJ 01
01:05:59 01:07:00 61 $12.10
Total amount: $12.10
CYLL 01
01:06:01 01:08:03 122 $24.40
28:15:41 28:16:05 24 $3.85
Total amount: $28.25
aaa 01
02:00:01 04:23:59 4318 $638.80
Total amount: $638.80

 

AC代码:

/*
1.判断记录好坏,把所有记录以string存起来,按照字典序排序,相邻的两条记录满足要求:第一条为on-line且第二条为off-line,才是成功匹配;
2.采用计算00: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;
struct customNode{
	string month;
	vector<string> online;
	vector<string> offline;
	vector<pair<string, string>> recordTag;
	vector<pair<string, string>> pairRecord;
	vector<pair<int, int>> eachCost;
	int total;
	customNode() :month(""), online(0), offline(0), eachCost(0), total(0){};
};
int str2int(string a){ return (a[0] - '0') * 10 + a[1] - '0'; }

int calculateCostFromZero(string a, vector<int>& rate)
{//计算从00:00:00到某个时间的耗费
	int rateSum = 0;//一天的总和
	for (int i = 0; i < 24; i++)
	{
		rateSum += rate[i] * 60;
	}
	int day = str2int(a.substr(3, 2));//天数
	int hour = str2int(a.substr(6, 2));//小时数
	int minute = str2int(a.substr(9, 2));//小时数
	int totalCost = day*rateSum;
	totalCost += minute*rate[hour];

	for (int i = 0; i < hour; i++)
	{
		totalCost += rate[i] * 60;
	}
	return totalCost;
}
int calculateMinutesFromZero(string a)
{//计算从00:00:00到某个时间的分钟数
	int day = str2int(a.substr(3, 2));//天数
	int hour = str2int(a.substr(6, 2));//小时数
	int minute = str2int(a.substr(9, 2));//小时数
	return day * 1440 + hour * 60 + minute;
}

pair<int, int> calculate(string a, string b, vector<int>& rate)
{//分别计算00:00:00和当前日期的差值

	int startCost = calculateCostFromZero(a, rate);
	int endCost = calculateCostFromZero(b, rate);
	int startMin = calculateMinutesFromZero(a);
	int endMin = calculateMinutesFromZero(b);

	return{ endCost - startCost, endMin - startMin };

}

pair<int, int> calculate2(string a, string b, vector<int>& rate)
{//计算差值的方法不是很好
	int startHour = str2int(a.substr(6, 2));//计算开始所在的小时
	int endHour = str2int(b.substr(6, 2));//计算结束时所在的小时
	int startNoDay = startHour * 60 + str2int(a.substr(9, 2));//计算H*60+m,单位为分钟
	int endNoDay = endHour * 60 + str2int(b.substr(9, 2));//计算H*60+m,单位为分钟

	int startWithDay = str2int(a.substr(3, 2)) * 1440 + startNoDay;//加上天数,单位为分钟
	int endWithDay = str2int(b.substr(3, 2)) * 1440 + endNoDay;//加上天数,单位为分钟
	int days = (endWithDay - startWithDay) / 1440;//查看隔了多少天
	int total = 0;
	for (int j = 0; j < days; j++)
	{//每多一天,都需要加上24小时的计费
		for (int i = 0; i < 24; i++)
			total += 60 * rate[i];
	}
	int recent = startNoDay;
	if (startNoDay > endNoDay)
	{
		endHour += 24;//如果起始的分钟数大于结束的分钟数,结束在第一天之后(有可能是2,3,4天),直接+24,便于统计
		endNoDay += 24 * 60;//No也需要加上24*60
	}
	for (int i = startHour + 1; i <= endHour && endHour != startHour; ++i)
	{//开始统计
		total += (i * 60 - recent)*rate[i - 1];
		recent = i * 60;
	}
	total += (endNoDay - recent)*rate[endHour];
	int diff = endWithDay - startWithDay;
	return{ total, diff };

}
bool cmpRecordTag(const pair<string, string>&a, const pair<string, string>&b)
{
	return a.first < b.first;
}
int main(void)
{

	vector<int> rate(48);// = { 10, 10, 10, 10, 10, 10, 20, 20, 20, 15, 15, 15, 15, 15, 15, 15, 20, 30, 20, 15, 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 15, 15, 15, 15, 15, 15, 15, 20, 30, 20, 15, 15, 10, 10, 10 };
	//int rateSum = 0;
	//for (int i = 0; i < 24; i++)
	//{
	//	rateSum += rate[i]*60;
	//}
	//vector<pair<int, int>> temp(0);
	//temp.push_back(calculate("01:28:23:41", "01:28:23:42", rate));
	//temp.push_back(calculate("01:28:15:41", "01:28:16:05", rate));
	//temp.push_back(calculate("01:01:05:59", "01:01:07:00", rate));
	//temp.push_back(calculate("01:02:00:01", "01:04:23:59", rate));
	//temp.push_back(calculate("01:01:06:01", "01:01:08:03", rate));
	//
	for (int i = 0; i < 24; i++)
	{
		scanf("%d", &rate[i]);
		rate[i + 24] = rate[i];
	}
	int recordNum;
	cin >> recordNum;
	map<string, customNode> m;
	vector<string> nameList(0);
	for (int i = 0; i < recordNum; i++)
	{//输入各条记录
		string name, time, tag;
		cin >> name >> time >> tag;
		if (m.find(name) == m.end())
			nameList.push_back(name);

		m[name].recordTag.push_back({ time, tag });
	}

	//直接sort,则string就是按照字典序进行排列
	sort(nameList.begin(), nameList.end());

	for (int i = 0; i < nameList.size(); i++)
	{
		string name = nameList[i];
		sort(m[name].recordTag.begin(), m[name].recordTag.end(), cmpRecordTag);
		m[name].total = 0;
		for (int j = 0; j + 1< m[name].recordTag.size(); j++)
		{
			if (m[name].recordTag[j].second == "on-line"&&m[name].recordTag[j + 1].second == "off-line")
			{//当前记录为on-line,且下一条为off-line,则匹配成功
				m[name].pairRecord.push_back({ m[name].recordTag[j].first.substr(3), m[name].recordTag[j + 1].first.substr(3) });
				m[name].eachCost.push_back(calculate(m[name].recordTag[j].first, m[name].recordTag[j + 1].first, rate));
				m[name].total += m[name].eachCost.back().first;
			}
		}
		if (m[name].pairRecord.size() != 0)
		{//题目只确保至少有一条成功匹配的记录,但是没有说每个人至少有一条成功匹配的记录
			//没成功匹配记录的人就不输出
			cout << name << " " << m[name].recordTag[0].first.substr(0, 2) << endl;
			for (int j = 0; j < m[name].pairRecord.size(); j++)
			{
				cout << m[name].pairRecord[j].first << " " << m[name].pairRecord[j].second << " " << m[name].eachCost[j].second << " $";
				printf("%.2f", m[name].eachCost[j].first / 100.0);
				cout << endl;
			}
			printf("Total amount: $%.2f", m[name].total / 100.0);
			cout << endl;
		}

	}


	return 0;
}

1015. Reversible Primes (20)

1.题目要求给出一个数N,该数在D进制下,数字位翻转后是否仍为质数。目前解法同时判断N和转化后的数是否同时为质数。

2.需要熟悉进制转换的方法。

3.进制转换的第一步,通过求余求出string,此时的string恰好是倒序的,直接转化为数字,判断质数即可

正确的进制转换:

while (num != 0)
{//求余,把它转化为d进制格式的数,但求出来的string刚好是反的
	char c = num%d + '0';
	s += c;
	num /= d;
}
for (int i = 0; i < s.size() / 2; i++)
	swap(s[i], s[s.size() - 1 - i]);

 

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

A reversible prime in any number system is a prime whose “reverse” in that number system is also a prime. For example in the decimal system 73 is a reversible prime because its reverse 37 is also a prime.

Now given any two positive integers N (< 105) and D (1 < D <= 10), you are supposed to tell if N is a reversible prime with radix D.

Input Specification:

The input file consists of several test cases. Each case occupies a line which contains two integers N and D. The input is finished by a negative N.

Output Specification:

For each test case, print in one line “Yes” if N is a reversible prime with radix D, or “No” if not.

Sample Input:

73 10
23 2
23 10
-2

Sample Output:

Yes
Yes
No

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;
/*
87767

*/
int main(void)
{
	vector<bool> prime(660000, true);
	prime[0] = false;
	prime[1] = false;
	prime[2] = true;
	for (int i = 2; i < 660000; i++)
	{
		if (prime[i])
		{
			for (int j = 2; j*i < 660000; j++)
			{
				prime[j*i] = false;
			}
		}
	}

	int n, d;
	while (scanf("%d", &n) != EOF)
	{
		if (n < 0) return 0;//以负数结束
		cin >> d;
		int num = n;
		string s = "";
		while (num != 0)
		{//求余,把它转化为d进制格式的数,但求出来的string刚好是反的
			char c = num%d + '0';
			s += c;
			num /= d;
		}
		//for (int i = 0; i < s.size() / 2; i++)
		//  swap(s[i], s[s.size() - 1 - i]);
		int reverse = 0;
		for (int i = 0; i < s.size(); i++)
		{
			reverse = (s[i] - '0') + reverse * d;
		}
		if (prime[n] && prime[reverse]) cout << "Yes" << endl;
		else cout << "No" << endl;
	}

	return 0;
}

1014. Waiting in Line (30)

1.该题是一道银行排队模拟题目,银行8点开门,17点关门。在17:00之前没有得到处理,则不再处理,如果已经得到处理,因为输出的范围为format HH:MM where HH is in [08, 17] and MM is in [00, 59],所以一直处理到17:59.

2.银行排队时间模拟,采用合适的结构进行编程

struct customNode{
	int process;//还需要处理多长的时间,每经过一次循环,--
	int cost;//该用户需要处理的时间
	string finished;//完成的时间
	customNode() :process(0), cost(0), finished(""){};
};

3.超过17:00(包括17:00)不再接受新用户,已经在处理的用户可以一直处理到17:59

QQ截图20151129190603

 

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

Suppose a bank has N windows open for service. There is a yellow line in front of the windows which devides the waiting area into two parts. The rules for the customers to wait in line are:

  • The space inside the yellow line in front of each window is enough to contain a line with M customers. Hence when all the N lines are full, all the customers after (and including) the (NM+1)st one will have to wait in a line behind the yellow line.
  • Each customer will choose the shortest line to wait in when crossing the yellow line. If there are two or more lines with the same length, the customer will always choose the window with the smallest number.
  • Customer[i] will take T[i] minutes to have his/her transaction processed.
  • The first N customers are assumed to be served at 8:00am.

Now given the processing time of each customer, you are supposed to tell the exact time at which a customer has his/her business done.

For example, suppose that a bank has 2 windows and each window may have 2 custmers waiting inside the yellow line. There are 5 customers waiting with transactions taking 1, 2, 6, 4 and 3 minutes, respectively. At 08:00 in the morning, customer1 is served at window1 while customer2 is served at window2. Customer3 will wait in front of window1 and customer4 will wait in front of window2. Customer5 will wait behind the yellow line.

At 08:01, customer1 is done and customer5 enters the line in front of window1 since that line seems shorter now. Customer2 will leave at 08:02, customer4 at 08:06, customer3 at 08:07, and finally customer5 at 08:10.

Input

Each input file contains one test case. Each case starts with a line containing 4 positive integers: N (<=20, number of windows), M (<=10, the maximum capacity of each line inside the yellow line), K (<=1000, number of customers), and Q (<=1000, number of customer queries).

The next line contains K positive integers, which are the processing time of the K customers.

The last line contains Q positive integers, which represent the customers who are asking about the time they can have their transactions done. The customers are numbered from 1 to K.

Output

For each of the Q customers, print in one line the time at which his/her transaction is finished, in the format HH:MM where HH is in [08, 17] and MM is in [00, 59]. Note that since the bank is closed everyday after 17:00, for those customers who cannot be served before 17:00, you must output “Sorry” instead.

Sample Input

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

Sample Output

08:07
08:06
08:10
17:00
Sorry
//#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 1 4 4
599 540 1 2
1 2 3 4
*/
struct customNode{
	int process;//还需要处理多长的时间,每经过一次循环,--
	int cost;//该用户需要处理的时间
	string finished;//完成的时间
	customNode() :process(0), cost(0), finished(""){};
};
string int2str(int a)
{//数字转string
	char b = a / 10 + '0';
	char c = a % 10 + '0';
	string ans = "1";
	ans += b;
	ans += c;
	return ans.substr(1);
}
string recordTime(int a)
{//int转时间
	int hour = a / 60 + 8;
	int min = a % 60;
	string ans = int2str(hour) + ":" + int2str(min);
	//cout << ans << endl;
	return ans;
}
int main(void) {

	int n, m, k, q;//n为银行窗口数,m为每个窗口的黄线内容量,k个客户,q是查询序列
	cin >> n >> m >> k >> q;
	vector<customNode> custom(k);
	for (int i = 0; i < k; i++)
	{//输入用户需要处理的时间
		cin >> custom[i].process;
		custom[i].finished = "";
		custom[i].cost = custom[i].process;//初始化用户需处理的时间
	}

	//窗口队列,每个窗口为一个队列
	vector<queue<int>> window(n);
	int input = 0;
	for (; input < n*m&input < k; input++)
	{//把客户压进窗口的队列
		window[input%n].push(input);
	}

	//10个小时,按照一分钟一分钟地进行计算
	for (int i = 0; i < 599; i++)
	{//一直可以处理到17:59
		bool allFinished = true;//全部处理完毕
		for (int j = 0; j < n; j++)
		{
			if (window[j].empty()) continue;//队列为空意味着等待队列无人了。因为窗口一有位置,就会马上插入等待队列中的人。

			allFinished = false;//窗口中仍有需要处理的用户

			if (i >= 540)
			{//超过17:00的不再接收新的用户处理
				int tmp = window[j].front(); //读取当前窗口的第一个用户
				if (custom[tmp].process == custom[tmp].cost)
				{//如果这些用户还没有被处理,即process==cost,现在已经超过17点,那么直接弹出,不再处理
					while (!window[j].empty())
					{//后面的用户肯定也没有处理,直接弹出
						window[j].pop();
					}
					continue;//该窗口已经为空,直接下一个窗口
				}
			}

			int p = window[j].front();//读取当前窗口的第一个用户
			custom[p].process--;//该用户处理时间减1分钟
			if (custom[p].process == 0)
			{//如果处理时间为0,证明客户处理完毕
				custom[p].finished = recordTime(i + 1);
				window[j].pop();//
				if (input<k&&i<539)
				{//如果input小于k,即仍有人需要服务,并且时间小于17:00,则进行排队处理
					window[j].push(input++);
				}
			}
		}
	}


	for (int i = 0; i < q; i++)
	{//输入查询队列
		int query;
		cin >> query;
		if (custom[query - 1].process != 0)
			cout << "Sorry" << endl;
		else
			cout << custom[query - 1].finished << endl;
	}
	return 0;
}

1013. Battle Over Cities (25)

1.题目求当一个城市被敌人占领,还需要多少条公路才能把剩余的城市连通。可以使用并查集来求解。

2.采用邻接矩阵才不会超内存,一开始采用edge的结构体存储,结果出现段错误(内存超出要求)

3.采用并查集的方法,统计时,遇到破坏的城市则不处理,否则进行合并

4.最终检查并查集的集合数,集合数-2就是结果(集合数m减去破坏的城市,该城市为单独一个集合,即m-1,令n=m-1,剩下的集合数n,需要采用n-1条边才能连接起来)

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

It is vitally important to have all the cities connected by highways in a war. If a city is occupied by the enemy, all the highways from/toward that city are closed. We must know immediately if we need to repair any other highways to keep the rest of the cities connected. Given the map of cities which have all the remaining highways marked, you are supposed to tell the number of highways need to be repaired, quickly.

For example, if we have 3 cities and 2 highways connecting city1-city2 and city1-city3. Then if city1 is occupied by the enemy, we must have 1 highway repaired, that is the highway city2-city3.

Input

Each input file contains one test case. Each case starts with a line containing 3 numbers N (<1000), M and K, which are the total number of cities, the number of remaining highways, and the number of cities to be checked, respectively. Then M lines follow, each describes a highway by 2 integers, which are the numbers of the cities the highway connects. The cities are numbered from 1 to N. Finally there is a line containing K numbers, which represent the cities we concern.

Output

For each of the K cities, output in a line the number of highways need to be repaired if that city is lost.

Sample Input

3 2 3
1 2
1 3
1 2 3

Sample Output

1
0
0

 

//#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>
/*
1 0 1
1
输出 0

*/
using namespace std;
struct edgeNode{
	int a, b;
	edgeNode() :a(0), b(0){};
};
int find(int k, vector<int>&r)
{
	if (r[k] == k)
		return r[k];
	else
	{
		r[k] = find(r[k], r);
		return r[k];
	}
}
int main(void) {

	int n, m, k;
	cin >> n >> m >> k;
	n++;//城市从1开始,方便操作
	vector<vector<bool>> w(n, vector<bool>(n, false));//使用邻接矩阵存储,避免超时超内存,之前使用edge存储,结果段错误(超内存了)
	for (int i = 0; i < m; i++)
	{//输入边
		int a, b;
		cin >> a >> b;
		w[a][b] = true;
		w[b][a] = true;
	}
	for (int i = 0; i < k; i++)
	{
		int city;
		cin >> city;
		static vector<int> r(n, 0);
		for (int i = 0; i < n; i++)
			r[i] = i;
		//r[city] = 10000;
		for (int i = 1; i < n; i++)
		{
			if (i == city) continue;
			for (int j = i; j < n; j++)
			{
				if (j == city) continue;
				if (w[i][j])
					r[find(j, r)] = find(i, r);//否则合并两个城市
			}
		}
		int sum = -2;
		for (int i = 1; i < n; i++)
			if (r[i] == i) sum++;

		//如果只有1个城市,则不用修路了
		if (n-1 == 1)
			sum = 0;
		cout << sum << endl;
	}


	return 0;
}

1012. The Best Rank (25)

1.题目要求输出学生最好的排名,如果多个科目的排名相同,则优先考虑是平均分A,再依次为C,M,E。

2.通过重写不同的cmp函数,使用algorithm.h里面的sort进行排序

3.如果分数相同,则排名相同,例如90,80,80,80,70,则排名为1,2,2,2,5。这个题目没有明确说明,但是实际上要这样排名。

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

To evaluate the performance of our first year CS majored students, we consider their grades of three courses only: C – C Programming Language, M – Mathematics (Calculus or Linear Algebra), and E – English. At the mean time, we encourage students by emphasizing on their best ranks — that is, among the four ranks with respect to the three courses and the average grade, we print the best rank for each student.

For example, The grades of C, M, E and A – Average of 4 students are given as the following:

StudentID  C  M  E  A
310101     98 85 88 90
310102     70 95 88 84
310103     82 87 94 88
310104     91 91 91 91

Then the best ranks for all the students are No.1 since the 1st one has done the best in C Programming Language, while the 2nd one in Mathematics, the 3rd one in English, and the last one in average.

Input

Each input file contains one test case. Each case starts with a line containing 2 numbers N and M (<=2000), which are the total number of students, and the number of students who would check their ranks, respectively. Then N lines follow, each contains a student ID which is a string of 6 digits, followed by the three integer grades (in the range of [0, 100]) of that student in the order of C, M and E. Then there are M lines, each containing a student ID.

Output

For each of the M students, print in one line the best rank for him/her, and the symbol of the corresponding rank, separated by a space.

The priorities of the ranking methods are ordered as A > C > M > E. Hence if there are two or more ways for a student to obtain the same best rank, output the one with the highest priority.

If a student is not on the grading list, simply output “N/A”.

Sample Input

5 6
310101 98 85 88
310102 70 95 88
310103 82 87 94
310104 91 91 91
310105 85 90 90
310101
310102
310103
310104
310105
999999

Sample Output

1 C
1 M
1 E
1 A
3 A
N/A
//#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;
struct student{
	int c, m, e, rank;
	int a;
	string course, ID;
	int tmpRank;//用来存在不同状态下的排名,主要是更新并列排名
	student() :c(0), m(0), e(0), a(0), rank(9999999), tmpRank(9999999), course(""), ID(""){};
};
bool cmpC(const student&a, const student&b)
{
	if (a.c > b.c) return true;
	else return false;
}
bool cmpM(const student&a, const student&b)
{
	if (a.m > b.m) return true;
	else return false;
}
bool cmpE(const student&a, const student&b)
{
	if (a.e > b.e) return true;
	else return false;
}
bool cmpA(const student&a, const student&b)
{
	if (a.a > b.a) return true;
	else return false;
}
int main(void) {

	int n, m;
	cin >> n >> m;
	vector<student> stu(n);
	for (int i = 0; i < n; i++)
	{
		cin >> stu[i].ID >> stu[i].c >> stu[i].m >> stu[i].e;
		stu[i].a = (stu[i].c + stu[i].m + stu[i].e);
		stu[i].course = "";
		stu[i].rank = 9999999;
	}
	//比较平均分
	sort(stu.begin(), stu.end(), cmpA);
	for (int i = 0; i < n; i++)
	{
		if (i == 0)
			stu[i].tmpRank = 0;
		else if (stu[i].a == stu[i - 1].a)
			stu[i].tmpRank = stu[i - 1].tmpRank;//如果分数相同,则排名相同
		else
			stu[i].tmpRank = i;//分数不同,则是i,例如 100 90 90 80 ,排名应该为1,2,2,4
		if (stu[i].rank > stu[i].tmpRank + 1)
		{
			stu[i].rank = stu[i].tmpRank + 1;
			stu[i].course = "A";
		}
	}
	//比较C语言
	sort(stu.begin(), stu.end(), cmpC);
	for (int i = 0; i < n; i++)
	{
		if (i == 0)
			stu[i].tmpRank = 0;
		else if (stu[i].c == stu[i - 1].c)
			stu[i].tmpRank = stu[i - 1].tmpRank;//如果分数相同,则排名相同
		else
			stu[i].tmpRank = i;//分数不同,则是i,例如 100 90 90 80 ,排名应该为1,2,2,4
		if (stu[i].rank > stu[i].tmpRank + 1)
		{
			stu[i].rank = stu[i].tmpRank + 1;
			stu[i].course = "C";
		}
	}
	//比较Mathematics
	sort(stu.begin(), stu.end(), cmpM);
	for (int i = 0; i < n; i++)
	{
		if (i == 0)
			stu[i].tmpRank = 0;
		else if (stu[i].m == stu[i - 1].m)
			stu[i].tmpRank = stu[i - 1].tmpRank;//如果分数相同,则排名相同
		else
			stu[i].tmpRank = i;//分数不同,则是i,例如 100 90 90 80 ,排名应该为1,2,2,4
		if (stu[i].rank > stu[i].tmpRank + 1)
		{
			stu[i].rank = stu[i].tmpRank + 1;
			stu[i].course = "M";
		}
	}
	//比较English
	sort(stu.begin(), stu.end(), cmpE);
	for (int i = 0; i < n; i++)
	{
		if (i == 0)
			stu[i].tmpRank = 0;
		else if (stu[i].e == stu[i - 1].e)
			stu[i].tmpRank = stu[i - 1].tmpRank;//如果分数相同,则排名相同
		else
			stu[i].tmpRank = i;//分数不同,则是i,例如 100 90 90 80 ,排名应该为1,2,2,4
		if (stu[i].rank > stu[i].tmpRank + 1)
		{
			stu[i].rank = stu[i].tmpRank + 1;
			stu[i].course = "E";
		}
	}
	map<string, student> ma;
	for (int i = 0; i < n; i++)
	{
		ma[stu[i].ID] = stu[i];
	}

	for (int i = 0; i < m; i++)
	{
		string tmp;
		cin >> tmp;
		if (ma.find(tmp) == ma.end())
			cout << "N/A" << endl;
		else
			cout << ma[tmp].rank << " " << ma[tmp].course << endl;
	}
	return 0;
}

1011. World Cup Betting (20)

1.该题目要求按照指定的计算公式求奖金。

2.最后的公式为(a*b*c*0.65-1)*2

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

With the 2010 FIFA World Cup running, football fans the world over were becoming increasingly excited as the best players from the best teams doing battles for the World Cup trophy in South Africa. Similarly, football betting fans were putting their money where their mouths were, by laying all manner of World Cup bets.

Chinese Football Lottery provided a “Triple Winning” game. The rule of winning was simple: first select any three of the games. Then for each selected game, bet on one of the three possible results — namely W for win, T for tie, and L for lose. There was an odd assigned to each result. The winner’s odd would be the product of the three odds times 65%.

For example, 3 games’ odds are given as the following:

 W    T    L
1.1  2.5  1.7
1.2  3.0  1.6
4.1  1.2  1.1

To obtain the maximum profit, one must buy W for the 3rd game, T for the 2nd game, and T for the 1st game. If each bet takes 2 yuans, then the maximum profit would be (4.1*3.0*2.5*65%-1)*2 = 37.98 yuans (accurate up to 2 decimal places).

Input

Each input file contains one test case. Each case contains the betting information of 3 games. Each game occupies a line with three distinct odds corresponding to W, T and L.

Output

For each test case, print in one line the best bet of each game, and the maximum profit accurate up to 2 decimal places. The characters and the number must be separated by one space.

Sample Input

1.1 2.5 1.7
1.2 3.0 1.6
4.1 1.2 1.1

Sample Output

T T W 37.98
//#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) {
	//精度要求,使用double或者float都可以AC
	vector<vector<double>> game(3, vector<double>(3, 0));
	string s[3] = { "W", "T", "L" };
	scanf("%lf %lf %lf %lf %lf %lf %lf %lf %lf", &game[0][0], &game[0][1], &game[0][2], &game[1][0], &game[1][1], &game[1][2], &game[2][0], &game[2][1], &game[2][2]);

	double ans[3];
	string out[3];
	ans[0] = game[0][0];
	ans[1] = game[1][0];
	ans[2] = game[2][0];
	out[0] = s[0];
	out[1] = s[0];
	out[2] = s[0];
	for (int i = 0; i < 3; i++)
	{
		for (int j = 1; j < 3; j++)
		{
			if (ans[i] < game[i][j])
			{
				ans[i] = game[i][j];
				out[i] = s[j];
			}
		}
	}
	double res = (ans[0] * ans[1] * ans[2] * 0.65 - 1) * 2;
	res += 0.00000001;
	cout << out[0] << " " << out[1] << " " << out[2] << " ";
	printf("%.2lf\n", res);

	return 0;
}

1010. Radix (25)

1.该题重点!题目给出N1,N2,tag,Radix,如果tag==1,则radix是N1的进制数,否则为N2的进制数;要求求出另外一个数是否存在在1到36进制中是否有和这个数相等的进制数。

2.最小的radix为t的各位数字最大值+1,否则不合理。

3.采用二分法寻找radix,设初始化l=各位数字最大值+1,r为sInt+1(比源数大1,因为存在t的进制数恰好为sInt+1的情况)。

4.tInt的进制数不一定小于36,题目没有明确说明,只是提到一个digit可以由字母或者数字表示,字母最大表示35,不要误以为这个是最大的radix。

QQ截图20151129190603

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

Given a pair of positive integers, for example, 6 and 110, can this equation 6 = 110 be true? The answer is “yes”, if 6 is a decimal number and 110 is a binary number.

Now for any pair of positive integers N1 and N2, your task is to find the radix of one number while that of the other is given.

Input Specification:

Each input file contains one test case. Each case occupies a line which contains 4 positive integers:
N1 N2 tag radix
Here N1 and N2 each has no more than 10 digits. A digit is less than its radix and is chosen from the set {0-9, a-z} where 0-9 represent the decimal numbers 0-9, and a-z represent the decimal numbers 10-35. The last number “radix” is the radix of N1 if “tag” is 1, or of N2 if “tag” is 2.

Output Specification:

For each test case, print in one line the radix of the other number so that the equation N1 = N2 is true. If the equation is impossible, print “Impossible”. If the solution is not unique, output the smallest possible radix.

Sample Input 1:

6 110 1 10

Sample Output 1:

2

Sample Input 2:

1 ab 1 2

Sample Output 2:

Impossible

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 c2int(char c)
{//字符转数字
    if (c <= '9'&&c >= '0')
        return c - '0';
    else if (c <= 'z'&&c >= 'a')
        return c - 'a' + 10;
    else return 0;
}
int main(void) {
 
    string n1, n2;
    int tag;
    unsigned long long radix;
    cin >> n1 >> n2 >> tag >> radix;
    string s, t;
    if (tag == 1)
    {//tag为1,则radix是n1的进制数
        s = n1;
        t = n2;
    }
    else if (tag == 2)
    {//tag为2,则radix是n2的进制数
        s = n2;
        t = n1;
    }
 
    unsigned long long sInt = 0;
    for (int i = 0; i < s.size(); i++)
    {//把s转为十进制
        sInt = sInt*radix + c2int(s[i]);
    }
 
    unsigned long long minRadix = 2;
    for (int i = 0; i < t.size(); i++)
    {//求出最小的进制数
        minRadix = max(minRadix, (unsigned long long)(c2int(t[i]) + 1));
    }
    bool flag = false;
    unsigned long long result = 0;
    unsigned long long r = sInt + 1;//必须+1
    unsigned long long l = minRadix;
    //使用二分法去查找合适的radix
    while (l <= r)//必须要有等号!!
    {//从最小的进制数开始遍历
        unsigned long long j = (l + r) / 2;//没说明j最大是36进制
        unsigned long long tInt = 0;
        for (int i = 0; i < t.size(); i++)
        {//j为t的进制数,求出t在j进制下的十进制大小
            tInt = tInt*j + c2int(t[i]);
            if (tInt > sInt)
            {//如果尚未统计完,tInt就被sInt大,没必要再统计下去
                //说明j进制使得tInt>sInt,t的进制数要比j小
                break;
            }
        }
        if (tInt == sInt)
        {
            flag = true;
            result = j;
            break;
        }
        else if (tInt > sInt)
        {
            r = j - 1;
            /*flag = false;
            break;*/
        }
        else l = j + 1;
    }
    if (flag) cout << result << endl;
    else cout << "Impossible" << endl;
 
 
    return 0;
}

堆排Heap Sort

#define LeftChild(i) (2*(i)+1)
void PercDown(vector<int>&num, int i, int n)
{
	int child;
	int tmp;
	for (tmp = num[i]; LeftChild(i) < n; i = child)
	{
		child = LeftChild(i);
		//如果右儿子存在,且值大于左儿子,则取右儿子
		if (child != n - 1 && num[child + 1] > num[child])
			child++;
		//如果父亲的值小于儿子,则继续下沉
		if (tmp < num[child])
			num[i] = num[child];
		else//否则,退出循环
			break;
	}
	num[i] = tmp;
}
//先建立堆
for (int i = n / 2; i >= 0; i--)
        PercDown(numCopy, i, n);
for (int i = n - 1; i>0; i--)
{//进行堆排
	swap(numCopy[0], numCopy[i]);
	PercDown(numCopy, 0, i);
}

1009. Product of Polynomials (25)

1.题目要求两个多项式相乘的结果。

2.直接创建1000*1000+1的数组,然后遍历所有相乘的组合情况。

This time, you are supposed to find A*B where A and B are two polynomials.

Input Specification:

Each input file contains one test case. Each case occupies 2 lines, and each line contains the information of a polynomial: K N1 aN1 N2 aN2 … NK aNK, where K is the number of nonzero terms in the polynomial, Ni and aNi (i=1, 2, …, K) are the exponents and coefficients, respectively. It is given that 1 <= K <= 10, 0 <= NK < … < N2 < N1 <=1000.

Output Specification:

For each test case you should output the product of A and B in one line, with the same format as the input. Notice that there must be NO extra space at the end of each line. Please be accurate up to 1 decimal place.

Sample Input

2 1 2.4 0 3.2
2 2 1.5 1 0.5

Sample Output

3 3 3.6 2 6.0 1 1.6

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>
using namespace std;
int main(void) {

	int n, m;
	cin >> n;
	vector<double> NK1(1001, 0);
	vector<double> NK2(1001, 0);
	vector<double> NK(1000001, 0);//直接创建1000*1000+1的数组
	//输入第一个多项式
	for (int i = 0; i < n; i++)
	{
		int temp;
		cin >> temp;
		cin >> NK1[temp];
	}

	cin >> m;
	//输入第二个多项式
	for (int i = 0; i < m; i++)
	{
		int temp;
		cin >> temp;
		cin >> NK2[temp];
	}
	//进行相乘
	for (int i = 0; i < 1001; i++)
	{
		for (int j = 0; j < 1001; j++)
		{
			if (NK1[i] != 0 && NK2[j] != 0)
			{
				NK[i + j] += NK1[i] * NK2[j];
			}
		}
	}

	int sum = 0;
	for (int i = 0; i < 1000001; i++)
	{//统计有多少项非零
		if (NK[i] != 0) sum++;
	}
	cout << sum;
	if (sum != 0) cout << " ";
	for (int i = 1000000; i >= 0; i--)
	{
		if (NK[i] != 0)
		{//输出非零的多项式
			printf("%d %.1lf", i, NK[i]);
			sum--;
			if (sum != 0) cout << " ";
		}

	}
	return 0;
}