1079. Total Sales of Supply Chain (25)

1.题目给出一些供应商和零售商,其中零售商处于供应链的多个级别,每个级别的售价都需要乘以一个系数,最后求出总售价。

2.使用树的结构存储供应商和零售商。

3.采用层次遍历(BFS)进行遍。

4.需要使用double进行存储,一开始发现下面几个耗时大的测试点不通过,所以考虑是精度不够或者溢出的原因,于是改为double类型,然后就通过了。

1079

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

A supply chain is a network of retailers(零售商), distributors(经销商), and suppliers(供应商)– everyone involved in moving a product from supplier to customer.

Starting from one root supplier, everyone on the chain buys products from one’s supplier in a price P and sell or distribute them in a price that is r% higher than P. Only the retailers will face the customers. It is assumed that each member in the supply chain has exactly one supplier except the root supplier, and there is no supply cycle.

Now given a supply chain, you are supposed to tell the total sales from all the retailers.

Input Specification:

Each input file contains one test case. For each case, the first line contains three positive numbers: N (<=105), the total number of the members in the supply chain (and hence their ID’s are numbered from 0 to N-1, and the root supplier’s ID is 0); P, the unit price given by the root supplier; and r, the percentage rate of price increment for each distributor or retailer. Then N lines follow, each describes a distributor or retailer in the following format:

Ki ID[1] ID[2] … ID[Ki]

where in the i-th line, Ki is the total number of distributors or retailers who receive products from supplier i, and is then followed by the ID’s of these distributors or retailers. Kj being 0 means that the j-th member is a retailer, then instead the total amount of the product will be given after Kj. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in one line the total sales we can expect from all the retailers, accurate up to 1 decimal place. It is guaranteed that the number will not exceed 1010.

Sample Input:

10 1.80 1.00
3 2 3 5
1 9
1 4
1 7
0 7
2 6 1
1 8
0 9
0 4
0 3

Sample Output:

42.4

AC代码:

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

struct Node{
	vector<int> list;
	bool isRetailer;
	int productCount;
	Node() :list(0), isRetailer(false), productCount(0){};
};
int main(void)
{
	int n;
	double rootPrice, higher;//需要使用double
	cin >> n >> rootPrice >> higher;
	vector<Node> chain(n);
	for (int i = 0; i < n; i++)
	{
		int tmp;
		cin >> tmp;
		if (tmp == 0)
		{//零售商
			chain[i].isRetailer = true;
			cin >> chain[i].productCount;
		}
		else
		{//供应商
			for (int j = 0; j < tmp; j++)
			{//输入下级供应商
				int nextLevel;
				cin >> nextLevel;
				chain[i].list.push_back(nextLevel);
			}
		}
	}

	queue<int> q;
	q.push(0);
	int count1 = 1, count2 = 0;
	double price = rootPrice;
	double totalSales = 0;
	//进行层次遍历
	while (!q.empty())
	{
		for (int i = 0; i < count1; i++)
		{
			int head = q.front(); q.pop();
			if (chain[head].isRetailer)
				totalSales += chain[head].productCount*price;
			else
			{
				for (int j = 0; j < chain[head].list.size(); j++)
				{
					q.push(chain[head].list[j]);
					count2++;
				}
			}
		}
		count1 = count2;
		count2 = 0;
		price *= (1 + higher / 100.0);
	}
	printf("%.1lf\n", totalSales);

	return 0;
}

1078. Hashing (25)

1.题目要求使用二次探测(平方探测)的方法进行哈希。

2.题目中提到MSize的最大值为10000,而比10000大的最小的一个质数为10007,刚开始误以为是10001,卡了一下

3.Quadratic probing即平方探测,公式为h(x)=(Hash(x)+j*j)% MSize,Hash(x)=x%MSize。

4.其他的开放定址方法还有线性探测法,双散列等等。

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

The task of this problem is simple: insert a sequence of distinct positive integers into a hash table, and output the positions of the input numbers. The hash function is defined to be “H(key) = key % TSize” where TSize is the maximum size of the hash table. Quadratic probing (with positive increments only) is used to solve the collisions.

Note that the table size is better to be prime. If the maximum size given by the user is not prime, you must re-define the table size to be the smallest prime number which is larger than the size given by the user.

Input Specification:

Each input file contains one test case. For each case, the first line contains two positive numbers: MSize (<=104) and N (<=MSize) which are the user-defined table size and the number of input numbers, respectively. Then N distinct positive integers are given in the next line. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the corresponding positions (index starts from 0) of the input numbers in one line. All the numbers in a line are separated by a space, and there must be no extra space at the end of the line. In case it is impossible to insert the number, print “-” instead.

Sample Input:

4 4
10 6 4 15

Sample Output:

0 1 4 -

AC代码:

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

5 4
10 6 4 15
6 4
10 6 4 15

*/
int main(void)
{
	
	int mSize, n;
	cin >> mSize >> n;
	vector<bool> prime(10008, true);
	prime[0] = false;
	prime[1] = false;
	for (int i = 2; i < prime.size(); i++)
	{//处理质数
		if (prime[i])
		{
			for (int j = 2; j*i < prime.size(); j++)
				prime[j*i] = false;
		}
	}

	if (!prime[mSize])
	{//如果mSize不为质数,则把mSize改为比mSize大的最小质数
		for (int i = mSize + 1; i < prime.size(); i++)
		{
			if (prime[i])
			{
				mSize = i;
				break;
			}
		}
	}
	vector<int> num(n);
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &num[i]);
	}
	vector<bool> exist(mSize, false);
	vector<int> position(n, -1);
	for (int i = 0; i < n; i++)
	{
		int pos = num[i] % mSize;//直接哈希地址
		for (int j = 0; j < mSize; j++)
		{//二次探测
			int tmpPos = (pos + j*j) % mSize;
			if (!exist[tmpPos])
			{//如果有空位
				exist[tmpPos] = true;
				position[i] = tmpPos;
				break;
			}
		}
	}
	for (int i = 0; i < n; i++)
	{
		if (position[i] != -1)
			printf("%d", position[i]);
		else
			printf("-");
		if (i != n - 1)
			printf(" ");
	}
	cout << endl;
	return 0;
}

1077. Kuchiguse (20)

1.题目要求求每个句子后面的公共字符串,如果有则输出,如果没有则输出nai。

2.需要使用getline输入,避免空格断开。

3.其他没有太多特点的地方。

时间限制
100 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
HOU, Qiming

The Japanese language is notorious for its sentence ending particles. Personal preference of such particles can be considered as a reflection of the speaker’s personality. Such a preference is called “Kuchiguse” and is often exaggerated artistically in Anime and Manga. For example, the artificial sentence ending particle “nyan~” is often used as a stereotype for characters with a cat-like personality:

  • Itai nyan~ (It hurts, nyan~)
  • Ninjin wa iyada nyan~ (I hate carrots, nyan~)

Now given a few lines spoken by the same character, can you find her Kuchiguse?

Input Specification:

Each input file contains one test case. For each case, the first line is an integer N (2<=N<=100). Following are N file lines of 0~256 (inclusive) characters in length, each representing a character’s spoken line. The spoken lines are case sensitive.

Output Specification:

For each test case, print in one line the kuchiguse of the character, i.e., the longest common suffix of all N lines. If there is no such suffix, write “nai”.

Sample Input 1:

3
Itai nyan~
Ninjin wa iyadanyan~
uhhh nyan~

Sample Output 1:

nyan~

Sample Input 2:

3
Itai!
Ninjinnwaiyada T_T
T_T

Sample Output 2:

nai

AC代码:

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

int main(void)
{
	string nStr;
	getline(cin, nStr);
	int n = 0;
	for (int i = 0; i < nStr.size(); i++)
		n = n * 10 + nStr[i] - '0';
	vector<string> sentence(n);
	int minLen = INT_MAX;
	for (int i = 0; i < n; i++)
	{
		getline(cin,sentence[i]);
		minLen = min(minLen,(int) sentence[i].size());
	}
	string ans = "";
	bool diff = false;
	for (int i = 1; i <= minLen; i++)
	{
		char c = sentence[0][sentence[0].size() - i];
		for (int j = 1; j < sentence.size(); j++)
		{
			if (c != sentence[j][sentence[j].size() - i])
			{
				diff = true;
				break;
			}
		}
		if (diff) break;
		else ans = c + ans;
	}
	if (ans.size() == 0)
		cout << "nai" << endl;
	else
		cout << ans << endl;
	return 0;
}

1076. Forwards on Weibo (30)

1.题目给出用户follow了哪些用户,然后求在level层关系内最大的转发数。

2.该题需要采用合适的数据结构,本程序使用了用节点来进行存储,节点中有一个followers列表,记录了谁关注了该用户.

3.使用层次遍历,直到最大level。

4.需要注意,用一个hasForwarded数组记录哪些用户已经转发,每个用户只转发一次。

1076

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

Weibo is known as the Chinese version of Twitter. One user on Weibo may have many followers, and may follow many other users as well. Hence a social network is formed with followers relations. When a user makes a post on Weibo, all his/her followers can view and forward his/her post, which can then be forwarded again by their followers. Now given a social network, you are supposed to calculate the maximum potential amount of forwards for any specific user, assuming that only L levels of indirect followers are counted.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 positive integers: N (<=1000), the number of users; and L (<=6), the number of levels of indirect followers that are counted. Hence it is assumed that all the users are numbered from 1 to N. Then N lines follow, each in the format:

M[i] user_list[i]

where M[i] (<=100) is the total number of people that user[i] follows; and user_list[i] is a list of the M[i] users that are followed by user[i]. It is guaranteed that no one can follow oneself. All the numbers are separated by a space.

Then finally a positive K is given, followed by K UserID‘s for query.

Output Specification:

For each UserID, you are supposed to print in one line the maximum potential amount of forwards this user can triger, assuming that everyone who can view the initial post will forward it once, and that only L levels of indirect followers are counted.

Sample Input:

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

Sample Output:

4
5

 
AC代码:

//#include<string>
//#include <iomanip>
//#include<stack>
//#include<unordered_set>
//#include <sstream>
//#include "func.h"
//#include <list>
#include<unordered_map>
#include<set>
#include<queue>
#include<map>
#include<vector>
#include <algorithm>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
#include<stack>
using namespace std;
struct UserNode{
	vector<int> follower;
	UserNode() :follower(0){};
};
int main(void)
{
	int userSum, maxLevel;
	cin >> userSum >> maxLevel;
	vector<UserNode> user(userSum);
	for (int i = 0; i < user.size(); i++)
	{
		int followSum;
		scanf("%d", &followSum);
		for (int j = 0; j < followSum; j++)
		{//用户i的关注列表
			int follow;
			scanf("%d", &follow);
			user[follow - 1].follower.push_back(i);
		}
	}

	int querySum;
	scanf("%d", &querySum);
	vector<int> query(querySum);
	for (int i = 0; i < query.size(); i++)
	{
		scanf("%d", &query[i]);
		query[i]--;//题目命名为1~N,但是程序命名为0~N-1
	}
	for (int i = 0; i < query.size(); i++)
	{//对每个查询的用户进行层次遍历
		queue<int> q;
		q.push(query[i]);
		int count1 = 1;
		int count2 = 0;
		int level = 0;
		int totalForward = 0;
		vector<bool> hasForwarded(userSum, false);
		hasForwarded[query[i]] = true;
		while (!q.empty()&&level<maxLevel)
		{
			for (int j = 0; j < count1; j++)
			{
				int head = q.front();
				q.pop();
				for (int k = 0; k < user[head].follower.size(); k++)
				{
					if (!hasForwarded[user[head].follower[k]])
					{//每个人只转发一次,还没转发的人进行转发
						hasForwarded[user[head].follower[k]] = true;
						q.push(user[head].follower[k]);
						count2++;
						totalForward++;
					}
				}
			}
			level++;
			count1 = count2;
			count2 = 0;
		}
		printf("%d\n", totalForward);
	}

	return 0;
}

1075. PAT Judge (25)

1.主要是求排名,根据给定的规则排名。

2.该题有几个需要注意的点
1)-1表示提交了但是没有编译通过,在最终输出的时候需要显示0分
2)完全没有记录的,表示没有提交过,在最终输出的时候需要显示-(负号)
3)在排名时,要把0分的也进行排名,如下面的测试例子:

8 4 21
20 25 25 30
00002 2 12
00007 4 17
00005 1 19
00007 2 25
00005 1 20
00002 2 2
00005 1 15
00001 1 18
00004 3 25
00002 2 25
00005 3 22
00006 4 -1
00001 2 18
00002 1 20
00004 1 15
00002 4 18
00001 3 4
00001 4 2
00005 2 -1
00004 2 0
00008 4 0

正确答案应该为:
1 00002 63 20 25 - 18
2 00005 42 20 0 22 -
2 00007 42 - 25 - 17
2 00001 42 18 18 4 2
5 00004 40 15 0 25 -
6 00008 0 - - - 0

8号用户虽然0分,但是有提交过,所以排名是有的。

1075

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

The ranklist of PAT is generated from the status list, which shows the scores of the submittions. This time you are supposed to generate the ranklist for PAT.

Input Specification:

Each input file contains one test case. For each case, the first line contains 3 positive integers, N (<=104), the total number of users, K (<=5), the total number of problems, and M (<=105), the total number of submittions. It is then assumed that the user id’s are 5-digit numbers from 00001 to N, and the problem id’s are from 1 to K. The next line contains K positive integers p[i] (i=1, …, K), where p[i] corresponds to the full mark of the i-th problem. Then M lines follow, each gives the information of a submittion in the following format:

user_id problem_id partial_score_obtained

where partial_score_obtained is either -1 if the submittion cannot even pass the compiler, or is an integer in the range [0, p[problem_id]]. All the numbers in a line are separated by a space.

Output Specification:

For each test case, you are supposed to output the ranklist in the following format:

rank user_id total_score s[1] … s[K]

where rank is calculated according to the total_score, and all the users with the same total_score obtain the same rank; and s[i] is the partial score obtained for the i-th problem. If a user has never submitted a solution for a problem, then “-” must be printed at the corresponding position. If a user has submitted several solutions to solve one problem, then the highest score will be counted.

The ranklist must be printed in non-decreasing order of the ranks. For those who have the same rank, users must be sorted in nonincreasing order according to the number of perfectly solved problems. And if there is still a tie, then they must be printed in increasing order of their id’s. For those who has never submitted any solution that can pass the compiler, or has never submitted any solution, they must NOT be shown on the ranklist. It is guaranteed that at least one user can be shown on the ranklist.

Sample Input:

7 4 20
20 25 25 30
00002 2 12
00007 4 17
00005 1 19
00007 2 25
00005 1 20
00002 2 2
00005 1 15
00001 1 18
00004 3 25
00002 2 25
00005 3 22
00006 4 -1
00001 2 18
00002 1 20
00004 1 15
00002 4 18
00001 3 4
00001 4 2
00005 2 -1
00004 2 0

Sample Output:

1 00002 63 20 25 - 18
2 00005 42 20 0 22 -
2 00007 42 - 25 - 17
2 00001 42 18 18 4 2
5 00004 40 15 0 25 -

AC代码:

//#include<string>
//#include <iomanip>
//#include<stack>
//#include<unordered_set>
//#include <sstream>
//#include "func.h"
//#include <list>
#include<unordered_map>
#include<set>
#include<queue>
#include<map>
#include<vector>
#include <algorithm>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
#include<stack>
using namespace std;
/*
8 4 20
20 25 25 30
00002 2 12
00007 4 17
00005 1 19
00007 2 25
00005 1 20
00002 2 2
00005 1 15
00001 1 18
00004 3 25
00002 2 25
00005 3 22
00006 4 -1
00001 2 18
00002 1 20
00004 1 15
00002 4 18
00001 3 4
00001 4 2
00005 2 -1
00004 2 0


8 4 21
20 25 25 30
00002 2 12
00007 4 17
00005 1 19
00007 2 25
00005 1 20
00002 2 2
00005 1 15
00001 1 18
00004 3 25
00002 2 25
00005 3 22
00006 4 -1
00001 2 18
00002 1 20
00004 1 15
00002 4 18
00001 3 4
00001 4 2
00005 2 -1
00004 2 0
00008 4 0

1 1 1
20
00001 1 15

*/
struct UserNode{
	int id;
	int rank;
	vector<int> score;
	int totalScore;
	int perfectSubmit;
	int noSubmit;
	UserNode() :id(0), rank(0), score(0), totalScore(0), perfectSubmit(0),noSubmit(0){};
	UserNode(vector<int> a) :id(0), rank(0), score(a), totalScore(0), perfectSubmit(0), noSubmit(0){};
};
bool cmp(const UserNode&a, const UserNode&b)
{
	if (a.totalScore > b.totalScore)
		return true;
	else if (a.totalScore == b.totalScore)
	{
		if (a.perfectSubmit > b.perfectSubmit)
			return true;
		else if (a.perfectSubmit == b.perfectSubmit && a.id < b.id)
			return true;
		else 
			return false;
	}
	else return false;
}
int main(void)
{
	int userSum, problemSum, submitSum;
	cin >> userSum >> problemSum >> submitSum;
	vector<UserNode> user(userSum);
	for (int i = 0; i < user.size(); i++)
	{//初始化每个用户的每个题目的分数
		user[i].score = vector<int>(problemSum, -2);
	}
	vector<int> fullScore(problemSum);
	for (int i = 0; i < fullScore.size(); i++)
	{//输入满分的分值
		cin >> fullScore[i];
	}

	for (int i = 0; i < submitSum; i++)
	{//输入提交记录
		int id,problemID, score;
		scanf("%d %d %d", &id, &problemID, &score);
		user[id - 1].id = id;//记录id
		user[id - 1].score[problemID - 1] = max(user[id - 1].score[problemID - 1],score);//取最高分,-1表示没有通过编译
	}
	for (int i = 0; i < user.size(); i++)
	{//统计学生的具体成绩
		user[i].totalScore = 0;
		for (int j = 0; j < problemSum; j++)
		{
			if (user[i].score[j] >=0)//大于等于0,即通过编译器
				user[i].totalScore += user[i].score[j];
			else //-1为提交了没通过编译器,-2为没提交
				user[i].noSubmit++;

			if (user[i].score[j] == fullScore[j])//如果分数是满分,perfect++
				user[i].perfectSubmit++;
		}
	}
	sort(user.begin(), user.end(), cmp);
	user[0].rank = 1;//一个用户排名第一
	printf("%d %05d %d", user[0].rank, user[0].id, user[0].totalScore);
	for (int j = 0; j < problemSum; j++)
	{
		if (user[0].score[j] >=0)
			printf(" %d", user[0].score[j]);
		else if (user[0].score[j] == -1)
			printf(" 0");//-1,提交了不通过,0分
		else//-2,没有提交过
			printf(" -");
	}
	printf("\n");
	for (int i = 1; i < user.size(); i++)
	{
		//即使分数为0的,也要统计排名
		if (user[i].totalScore == user[i-1].totalScore)
			user[i].rank = user[i - 1].rank;
		else
			user[i].rank = i+1;

		if (user[i].noSubmit != problemSum)
		{		//输出用户信息
			printf("%d %05d %d", user[i].rank, user[i].id, user[i].totalScore);
			for (int j = 0; j < problemSum; j++)
			{
				if (user[i].score[j] >= 0)//如果用户的分数大于等于0,则输出分数
					printf(" %d", user[i].score[j]);
				else if (user[i].score[j] == -1)
					printf(" 0");//-1,提交了不通过,0分
				else //-2,没有提交过,输出横线
					printf(" -");
			}
			printf("\n");
		}
	}
	return 0;
}

1074. Reversing Linked List (25)

1.该题要求求出翻转的链表,与leetcode中的Reverse Linked List 和Reverse Linked List II相似。

2.这次解法并没有采用链表操作,而是把链表转化为数组,对数组进行操作

1074

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

Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K = 3, then you must output 3→2→1→6→5→4; if K = 4, you must output 4→3→2→1→5→6.

Input Specification:

Each input file contains one test case. For each case, the first line contains the address of the first node, a positive N (<= 105) which is the total number of nodes, and a positive K (<=N) which is the length of the sublist to be reversed. The address of a node is a 5-digit nonnegative integer, and NULL is represented by -1.

Then N lines follow, each describes a node in the format:

Address Data Next

where Address is the position of the node, Data is an integer, and Next is the position of the next node.

Output Specification:

For each case, output the resulting ordered linked list. Each node occupies a line, and is printed in the same format as in the input.

Sample Input:

00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218

Sample Output:

00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1

 
AC代码:

//#include<string>
//#include <iomanip>
//#include<stack>
//#include<unordered_set>
//#include <sstream>
//#include "func.h"
//#include <list>
#include<unordered_map>
#include<set>
#include<queue>
#include<map>
#include<vector>
#include <algorithm>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
#include<stack>
using namespace std;
/*
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218

00100 6 3
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218

00100 6 2
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218

00100 6 0
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218

00100 6 1
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218

00100 6 5
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218

00100 6 6
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
*/
struct ListNode{
	int val;
	int add;
	ListNode*next;
	ListNode(int x) :val(x), next(NULL){};
	ListNode() :val(0), next(NULL){};
};
int main(void)
{
	vector<ListNode> list(100001,ListNode(-1));
	int head, recordSum, step;
	cin >> head >> recordSum >> step;
	for (int i = 0; i < recordSum; i++)
	{
		int now, val, next;
		scanf("%d %d %d", &now, &val, &next);
		list[now].val = val;
		list[now].add = now;
		if (next != -1)
		{
			list[now].next = &list[next];
			list[next].add = next;
		}
	}
	vector<int> num(100001, -1);//记录地址,地址是唯一的
	int idx=0;
	ListNode* root = &list[head];
	while (root)
	{
		num[idx++] = root->add;
		root = root->next;
	}

	if (step!=0)//等于0时,会进入死循环
		for (int i = 0; i+step <=idx; i+=step)
		{
			for (int j = 0; j < step / 2; j++)
			{
				swap(num[j+i], num[step + i - 1 - j]);
			}
		}
	for (int i = 0; i < idx; i++)
	{
		if (i != idx - 1)
			printf("%05d %d %05d\n", num[i], list[num[i]].val, num[i + 1]);
		else
			printf("%05d %d -1\n", num[i], list[num[i]].val);
	}




	return 0;
}

1073. Scientific Notation (20)

1.根据科学计数法,还原原来的整数。

2.根据E后面是正数还是负数,决定小数点左移还是右移。

3.我的算法是,先提取出正负号和E之间的数字(已经去掉小数点),即+1.234567E+04,经过提取后变为1234567,后续直接对这个字符串进行处理。

4.右移时,需要注意3种情况:

1)如+1.200E+03,为1200   ,刚好不需要补零和小数点;

2)如+1.234567E+04 为12345.67 , 需要补小数点;

3)如+1.2E+04 为12000 ,需要补零。

5.左移时,需要考虑两种情况:

1)如+1.2345E-00,只需要补上小数点;

2)-1.2345E-01  ,-1.2345E-02,- 1.2345E-03 ,需要在12345中,补上0和小数点。

时间限制
100 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
HOU, Qiming

Scientific notation is the way that scientists easily handle very large numbers or very small numbers. The notation matches the regular expression [+-][1-9]”.”[0-9]+E[+-][0-9]+ which means that the integer portion has exactly one digit, there is at least one digit in the fractional portion, and the number and its exponent’s signs are always provided even when they are positive.

Now given a real number A in scientific notation, you are supposed to print A in the conventional notation while keeping all the significant figures.

Input Specification:

Each input file contains one test case. For each case, there is one line containing the real number A in scientific notation. The number is no more than 9999 bytes in length and the exponent’s absolute value is no more than 9999.

Output Specification:

For each test case, print in one line the input number A in the conventional notation, with all the significant figures kept, including trailing zeros,

Sample Input 1:

+1.23400E-03

Sample Output 1:

0.00123400

Sample Input 2:

-1.2E+10

Sample Output 2:

-12000000000

AC代码:

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

/*
+1.2345E+00
+1.234567E+04
+1.2E+04
+1.200E+03
-1.200E+03

+1.2345E-00
+1.2345E-01
+1.2345E-02
+1.2345E-03

-1.2345E-00
-1.2345E-01
-1.2345E-02
-1.2345E-03
*/
int main(void)
{
	string str;
	cin >> str;

	string sign = "-";
	if (str[0] == '+') sign = "";
	int ePos = 0;//E的位置
	string ans = "";
	for (int i = 1; i < str.size(); i++)
	{
		if (str[i] == 'E')
		{
			ePos = i;
			break;
		}
		else if (str[i] != '.')
			ans += str[i];//去掉小数点和正负号,E后面的部分
	}
	bool right = (str[ePos+1] == '+');//如果E后面是+号,那么右边+0,即小数点左移
	int tenNum = 0;
	for (int i = ePos + 2; i < str.size(); i++)
		tenNum = tenNum * 10 + str[i] - '0';
	if (right)
	{
		int zeroSum = tenNum - (ans.size() - 1);
		if (zeroSum == 0)//如+1.200E+03,为1200
			ans = sign + ans;
		else if (zeroSum < 0)
		{//如+1.234567E+04 为12345.67,ans长度为7,tenNum为4,小数点右移4位
			string tmp = "";
			tmp = ans.substr(0, 1 + tenNum) + "." + ans.substr(1 + tenNum);
			ans = sign + tmp;
		}
		else if (zeroSum > 0)
		{//如+1.2E+04 为12000,补充零的个数为1,即ans为12,长度减1后为1. 然后4-1=3,补3个0
			for (int i = 0; i < zeroSum; i++)
				ans += '0';
			ans = sign + ans;
		}
	}
	else
	{//小数点左移
		if (tenNum == 0)//如果+1.2345E-00
			ans =sign+ str.substr(1, ePos-1);
		else
		{//tenNum>0
			for (int i = 0; i < tenNum - 1; i++)
			{
				ans = '0' + ans;
			}
			ans = sign + "0." + ans;
		}
	}
	cout << ans << endl;
	return 0;
}

1072. Gas Station (30)

1.题目要求一个加油站,能够到达所有的屋子,并且这个加油站到屋子的最小距离尽可能地大(实际上也应该,不然汽油挥发会影响人身安全啊啊啊)。

2.根据汽油站index排序时,不能使用string,要转换成int排序,避免出现G1<G123<G2<G23这样的情况。

3.通过dijkstra求每个加油站到各个屋子的距离,即dijkstra外加一个循环遍历。然后统计所有的最短路径和平均路径,进行排序。

4.最小距离一样的,根据平均距离来排序,平均距离仍然一样的,根据加油站的id来排序。

5.为了提高空间利用率,把加油站和屋子都统一成一个结构体,这个结构体数据的0~housesum用来表示屋子,housesum+1~housesum+1+gassum表示加油站。

1072

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

A gas station has to be built at such a location that the minimum distance between the station and any of the residential housing is as far away as possible. However it must guarantee that all the houses are in its service range.

Now given the map of the city and several candidate locations for the gas station, you are supposed to give the best recommendation. If there are more than one solution, output the one with the smallest average distance to all the houses. If such a solution is still not unique, output the one with the smallest index number.

Input Specification:

Each input file contains one test case. For each case, the first line contains 4 positive integers: N (<= 103), the total number of houses; M (<= 10), the total number of the candidate locations for the gas stations; K (<= 104), the number of roads connecting the houses and the gas stations; and DS, the maximum service range of the gas station. It is hence assumed that all the houses are numbered from 1 to N, and all the candidate locations are numbered from G1 to GM.

Then K lines follow, each describes a road in the format
P1 P2 Dist
where P1 and P2 are the two ends of a road which can be either house numbers or gas station numbers, and Dist is the integer length of the road.

Output Specification:

For each test case, print in the first line the index number of the best location. In the next line, print the minimum and the average distances between the solution and all the houses. The numbers in a line must be separated by a space and be accurate up to 1 decimal place. If the solution does not exist, simply output “No Solution”.

Sample Input 1:

4 3 11 5
1 2 2
1 4 2
1 G1 4
1 G2 3
2 3 2
2 G2 1
3 4 2
3 G3 2
4 G1 3
G2 G1 1
G3 G2 2

Sample Output 1:

G1
2.0 3.3

Sample Input 2:

2 1 2 10
1 G1 9
2 G1 20

Sample Output 2:

No Solution
//#include<string>
//#include<stack>
//#include<unordered_set>
//#include <sstream>
//#include "func.h"
//#include <list>
#include <iomanip>
#include<unordered_map>
#include<set>
#include<queue>
#include<map>
#include<vector>
#include <algorithm>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
#include<stack>
using namespace std;
/*
2 1 2 20
1 G1 9
2 G1 20

1 1 1 20
1 G1 9


4 3 11 5
1 2 2
1 4 2
1 G1 5
1 G2 3
2 3 2
2 G2 1
3 4 2
3 G3 2
4 G1 3
G2 G1 1
G3 G2 2

*/
struct Node{
	vector<pair<int,int>> list;//邻居
	bool visited;
	bool sured;
	long long cost;
	Node() :list(0), visited(false), sured(false), cost(INT_MAX){};
};
string num2string(int a)
{
	if (a == 0) return "0";
	string ans = "";
	while (a != 0)
	{
		char c = a % 10 + '0';
		ans = c + ans;
		a /= 10;
	}
	return ans;
	
}
struct resultNode{
	string gas;//不能够用string排序,避免G1,G123,G2,G23这样的情况
	int id;
	double min;
	double avg;
	double totalCost;
	resultNode(string s,int i, double m, double a) :gas(s), id(i), min(m), avg(a), totalCost(0){};
	resultNode() :gas(""), id(0), min(0), avg(0), totalCost(0){};
};
bool cmp(const resultNode&a, const resultNode&b)
{
	if (a.min > b.min)
		return true;
	else if (a.min == b.min && a.totalCost < b.totalCost)
		return true;
	else if (a.min == b.min && a.totalCost == b.totalCost && a.id < b.id)
		return true;
	else return false;

}
int main(void)
{
	int houseSum, gasSum, roadSum, serviceRange;
	cin >> houseSum>> gasSum>>roadSum>>serviceRange;
	vector<Node> place( houseSum+gasSum+1);//1~houseSum表示房子,houseSum+1~houseSum+gasSum表示加油站
	map<int,bool> gasStationNum;

	for (int i = 0; i < roadSum; i++)
	{
		int a = 0;
		char tmp[5];
		scanf("%s", tmp);
		if (tmp[0] == 'G')//加油站
		{
			a = 0;//1~houseSum表示房子,houseSum+1~houseSum+gasSum表示加油站
			for (int j = 1; j < 5 && tmp[j] != 0; j++)
				a = a * 10 + tmp[j] - '0';
			a += houseSum;//1~houseSum表示房子,houseSum+1~houseSum+gasSum表示加油站
		}
		else
		{
			a = 0;
			for (int j = 0; j < 5 && tmp[j] != 0; j++)
				a = a * 10 + tmp[j] - '0';
		}
		int b = 0;
		scanf("%s", tmp);
		if (tmp[0] == 'G')//加油站
		{
			b = 0;//1~houseSum表示房子,houseSum+1~houseSum+gasSum表示加油站
			for (int j = 1; j < 5 && tmp[j] != 0; j++)
				b = b * 10 + tmp[j] - '0';
			b += houseSum;//1~houseSum表示房子,houseSum+1~houseSum+gasSum表示加油站
		}
		else
		{
			b = 0;
			for (int j = 0; j < 5 && tmp[j] != 0; j++)
				b = b * 10 + tmp[j] - '0';
		}

		int cost;
		scanf("%d", &cost);
		place[a].list.push_back({ b, cost });
		place[b].list.push_back({ a, cost });
	}

	double minCost = INT_MAX;
	double totalCost = INT_MAX;
	vector<resultNode> ans(0);
	for (int nowGas = houseSum + 1; nowGas < houseSum + gasSum + 1; nowGas++)
	{
		bool canChoose = true;//记录是否能够选为加油站,后面服务范围会使用
		long long thisMinCost = INT_MAX;
		long long thisTotalCost = 0;
		vector<Node> v = place;//避免统计每个加油站时,数据已经存在,所以每次计算加油站,都新建一个节点vector

		//使用dijkstra算法统计单元最短路径
		v[nowGas].visited = true;
		v[nowGas].cost = 0;
		while (1)
		{
			int p = -1;
			for (int i = 0; i < v.size(); i++)
			{
				if (p == -1 && v[i].visited&&!v[i].sured)
					p = i;
				else if (p != -1 && v[i].visited && !v[i].sured && v[i].cost < v[p].cost)
					p = i;
			}
			if (p == -1) break;
			v[p].sured = true;
			if (p <= houseSum && v[p].cost > serviceRange)
			{//如果该点是房子,但是在服务距离之外,则false
				canChoose = false;
				break;
			}
			for (int i = 0; i < v[p].list.size(); i++)
			{
				int q = v[p].list[i].first;
				if (!v[q].sured && v[q].cost > v[p].cost + v[p].list[i].second)
				{
					v[q].visited = true;//标记为已经探望
					v[q].cost = v[p].cost + v[p].list[i].second;//更新最短路径
				}
			}
		}
		if (!canChoose) continue;//有些房子服务范围之外,不能选为gas
		for (int i = 1; i <= houseSum; i++)
		{//只统计房子部分,计算最短路径和总耗费
			thisMinCost = min(thisMinCost, v[i].cost);
			thisTotalCost += v[i].cost;
			if (!v[i].sured)
			{//有些房子没有到达,不能选为gas
				canChoose = false;
				break;
			}
		}
		if (!canChoose) continue;//有些房子没有到达,不能选为gas

		//存储结果
		minCost = thisMinCost;
		totalCost = thisTotalCost;
		string gasID = "G";
		gasID += num2string(nowGas - houseSum);
		double avg = thisTotalCost*1.0 / houseSum;
		ans.push_back(resultNode(gasID, nowGas - houseSum, thisMinCost, avg));
		ans.back().totalCost = thisTotalCost;

	}
	if (ans.size() == 0)
		printf("No Solution\n");
	else
	{
		sort(ans.begin(), ans.end(), cmp);
		cout << ans[0].gas << endl;
		printf("%.1lf %.1lf\n", ans[0].min, ans[0].avg);
	}

	return 0;
}

1071. Speech Patterns (25)

1.题目求一段string中,出现次数最高的word,word可包括数字和字母。Here a “word” is defined as a continuous sequence of alphanumerical characters separated by non-alphanumerical characters or the line beginning/end.

2.首先是字符串处理,把大写字母的全改为小写字母。

3.字符串分隔,遇到不是数字或者字母的字符,就进行分隔。

4.使用map来存储次数,最后再存到vector中排序输出。

5.需要使用scanf读取字符,不能使用getline。

1071

时间限制
300 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
HOU, Qiming

People often have a preference among synonyms of the same word. For example, some may prefer “the police”, while others may prefer “the cops”. Analyzing such patterns can help to narrow down a speaker’s identity, which is useful when validating, for example, whether it’s still the same person behind an online avatar.

Now given a paragraph of text sampled from someone’s speech, can you find the person’s most commonly used word?

Input Specification:

Each input file contains one test case. For each case, there is one line of text no more than 1048576 characters in length, terminated by a carriage return ‘\n’. The input contains at least one alphanumerical character, i.e., one character from the set [0-9 A-Z a-z].

Output Specification:

For each test case, print in one line the most commonly occurring word in the input text, followed by a space and the number of times it has occurred in the input. If there are more than one such words, print the lexicographically smallest one. The word should be printed in all lower case. Here a “word” is defined as a continuous sequence of alphanumerical characters separated by non-alphanumerical characters or the line beginning/end.

Note that words are case insensitive.

Sample Input:

Can1: "Can a can can a can?  It can!"

Sample Output:

can 5
//#include<string>
//#include<stack>
//#include<unordered_set>
//#include <sstream>
//#include "func.h"
//#include <list>
#include <iomanip>
#include<unordered_map>
#include<set>
#include<queue>
#include<map>
#include<vector>
#include <algorithm>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
#include<stack>
using namespace std;
/*
Here a "word is defined as a continuous sequence of alphanumerical characters separated by non-alphanumerical characters or the line beginning/end

*/
bool cmp(const pair<string, int>&a,const pair<string, 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)
{
	string s="";
	char c = '1';
	while (c!='\n')
	{
		scanf("%c", &c);
		s += c;
	}
	
	map<string, int> times;
	string word = "";
	for (int i = 0; i < s.size(); i++)
	{
		if ((s[i] >= 'a'&&s[i] <= 'z') || (s[i] >= 'A'&&s[i] <= 'Z') || (s[i] >= '0'&&s[i] <= '9'))
		{//是字母
			if ((s[i] >= 'A'&&s[i] <= 'Z'))
				s[i] = s[i] - 'A' + 'a';
			word += s[i];
		}
		else
		{//不是字母,则清空word
			if (word != "")
				times[word]++;
			word = "";
		}
	}

	vector<pair<string, int>> ans(0);
	for (map<string, int>::iterator ite = times.begin(); ite != times.end(); ite++)
	{
		ans.push_back( *ite);
	}
	sort(ans.begin(), ans.end(), cmp);

	cout << ans[0].first << " " << ans[0].second << endl;

	return 0;
}

1070. Mooncake (25)

1.物品可切分的背包问题,贪心算法可解。

2.卡在测试点2比较久,结果发现amount也需要使用double才能通过,使用long long或者int都不行。

3.贪心算法,每次取单位价格最高的mooncake。

存储结构


struct mooncakeNode{
	double amount;//需要使用double,才能通过测试点2
	double price;
	double unitPrice;
	mooncakeNode() :amount(0), price(0), unitPrice(0){};
};
时间限制
100 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

Mooncake is a Chinese bakery product traditionally eaten during the Mid-Autumn Festival. Many types of fillings and crusts can be found in traditional mooncakes according to the region’s culture. Now given the inventory amounts and the prices of all kinds of the mooncakes, together with the maximum total demand of the market, you are supposed to tell the maximum profit that can be made.

Note: partial inventory storage can be taken. The sample shows the following situation: given three kinds of mooncakes with inventory amounts being 180, 150, and 100 thousand tons, and the prices being 7.5, 7.2, and 4.5 billion yuans. If the market demand can be at most 200 thousand tons, the best we can do is to sell 150 thousand tons of the second kind of mooncake, and 50 thousand tons of the third kind. Hence the total profit is 7.2 + 4.5/2 = 9.45 (billion yuans).

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 positive integers N (<=1000), the number of different kinds of mooncakes, and D (<=500 thousand tons), the maximum total demand of the market. Then the second line gives the positive inventory amounts (in thousand tons), and the third line gives the positive prices (in billion yuans) of N kinds of mooncakes. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the maximum profit (in billion yuans) in one line, accurate up to 2 decimal places.

Sample Input:

3 200
180 150 100
7.5 7.2 4.5

Sample Output:

9.45

AC代码:

//#include<string>
//#include<stack>
//#include<unordered_set>
//#include <sstream>
//#include "func.h"
//#include <list>
#include <iomanip>
#include<unordered_map>
#include<set>
#include<queue>
#include<map>
#include<vector>
#include <algorithm>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
#include<stack>
using namespace std;
/*
3 2000
180 150 100
7.5 7.2 4.5
3 20
180 150 100
7.5 7.2 4.5

0 20
 
3 0
180 150 100
7.5 7.2 4.5

3 1
180 150 100
7.5 7.2 4.5
*/
struct mooncakeNode{
	double amount;//需要使用double,才能通过测试点2
	double price;
	double unitPrice;
	mooncakeNode() :amount(0), price(0), unitPrice(0){};
};
bool cmp(const mooncakeNode&a, const mooncakeNode&b)
{
	if (a.amount == b.amount && a.price >= b.price) return true;
	else
	return (double)a.price*b.amount > (double)b.price*a.amount;
}
int main(void)
{
	
	int n, marketNeed;
	cin >> n >> marketNeed;
	vector<mooncakeNode> mooncake(n);
	for (int i = 0; i < n; i++)
	{
		cin >> mooncake[i].amount;
	}
	for (int i = 0; i < n; i++)
	{//输入总价格和求出单位价格
		cin >> mooncake[i].price;
		if (mooncake[i].amount == 0)
		{
			mooncake[i].price = 0;
			mooncake[i].unitPrice = 0;
		}
		else
			mooncake[i].unitPrice = mooncake[i].price / mooncake[i].amount;
	}
	sort(mooncake.begin(), mooncake.end(), cmp);

	double profit=0;
	for (int i = 0; i < n && marketNeed!=0; i++)
	{
		if (mooncake[i].amount == marketNeed)
		{//如果刚好相等,则全部要了
			profit += mooncake[i].price;
			marketNeed -= mooncake[i].amount;
		}
		else if (mooncake[i].amount < marketNeed)
		{//如果数量小于市场需要,则全部要了
			profit += mooncake[i].price;
			marketNeed -= mooncake[i].amount;
		}
		else
		{//如果数量大于市场需要,则取市场需要部分即可
			profit += mooncake[i].price*marketNeed/mooncake[i].amount;
			marketNeed = 0;
		}
	}
	printf("%.2lf", profit);
	//cout << setprecision(2) << profit << endl;

	return 0;
}