1090. Highest Price in Supply Chain (25)

1.这道题目实则是一道关于的题目,树的每一层代表一个级别的供应商,树的高度越大,价格越高

如题目例子:

9 1.80 1.00
1 5 4 4 -1 4 5 3 6

构成的树为

QQ截图20151130193843

红色部分(0和8,两个)的价格最高,为1.8*1.01*1.01*1.01=1.85。

2.采用合适的数据结构存储节点,然后BFS进行层次遍历即可。

1090

时间限制
200 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. 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 highest price we can expect from some 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 they are numbered from 0 to N-1); P, the price given by the root supplier; and r, the percentage rate of price increment for each distributor or retailer. Then the next line contains N numbers, each number Si is the index of the supplier for the i-th member. Sroot for the root supplier is defined to be -1. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in one line the highest price we can expect from some retailers, accurate up to 2 decimal places, and the number of retailers that sell at the highest price. There must be one space between the two numbers. It is guaranteed that the price will not exceed 1010.

Sample Input:

9 1.80 1.00
1 5 4 4 -1 4 5 3 6

Sample Output:

1.85 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;
struct Node
{
	vector<int> list;
	Node() :list(0){};
};
int main(void)
{
	int n;
	double rootPrice;
	double higherPercent;
	cin >> n >> rootPrice >> higherPercent;
	vector<Node> supplier(n);
	int root;
	for (int i = 0; i < n; i++)
	{
		int Si;
		scanf("%d", &Si);
		if (Si == -1) root = i;//-1为根供应商
		else//i的上级供应商为Si
			supplier[Si].list.push_back(i);
	}

	//进行层次遍历
	queue<int> q;
	int count1 = 1, count2 = 0;
	q.push(root); 
	int level = 0;
	int lastLevelMember = 0;
	while (!q.empty())
	{
		for (int i = 0; i < count1; i++)
		{
			int head = q.front();
			q.pop();
			for (int j = 0; j < supplier[head].list.size(); j++)
			{
				q.push(supplier[head].list[j]);
				count2++;
			}
		}
		level++;
		lastLevelMember = count1;
		count1 = count2;
		count2 = 0;
	}
	double highestPrice = rootPrice;
	for (int i = 0; i < level-1; i++)
	{//level会把root也算作1层
		highestPrice *= (1 + higherPercent / 100.0);
	}
	printf("%.2lf %d\n", highestPrice, lastLevelMember);
	return 0;
}

1089. Insert or Merge (25)

1.给出一个初始的排列和一个经过N轮排序的排列,求出是使用插入还是归并排序,并输出下一轮的排列。

2.注意插入排序j=1开始。

3.根据题意,编写归并排序算法,如下:

	bool isMerge = false;
	for (int step = 1; step / 2 < n; step *= 2)
	{//步进初始为1,第二次为2,第三次为4,如此类推
		for (int i = 0; i < n; i += 2 * step)
		{
			vector<int> tmpArr(2 * step);
			int first = i;
			int second = i+step;
			int idx = 0;
			int k = 0;
			while (first<min(n,i+step)||second<min(n,i+2*step))
			{//通过first和second指针,把数组分为两个,然后进行归并排序
				if (first<min(n, i + step) && second<min(n, i + 2 * step))
				{
					if (num2[first] < num2[second])
						tmpArr[idx++] = num2[first++];
					else
						tmpArr[idx++] = num2[second++];
				}
				else if (first<min(n, i + step))//second已经遍历完,剩下first数组
					tmpArr[idx++] = num2[first++];
				else//first已经遍历完,剩下second数组
					tmpArr[idx++] = num2[second++];
			}
			for (int k = 0; k < 2 * step&&i + k < n; k++)
				num2[i + k] = tmpArr[k];
		}
		if (!isMerge&&num2 == target)
			isMerge = true;
		else if (isMerge)
			break;
	}
时间限制
200 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

According to Wikipedia:

Insertion sort iterates, consuming one input element each repetition, and growing a sorted output list. Each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there. It repeats until no input elements remain.

Merge sort works as follows: Divide the unsorted list into N sublists, each containing 1 element (a list of 1 element is considered sorted). Then repeatedly merge two adjacent sublists to produce new sorted sublists until there is only 1 sublist remaining.

Now given the initial sequence of integers, together with a sequence which is a result of several iterations of some sorting method, can you tell which sorting method we are using?

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (<=100). Then in the next line, N integers are given as the initial sequence. The last line contains the partially sorted sequence of the N numbers. It is assumed that the target sequence is always ascending. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in the first line either “Insertion Sort” or “Merge Sort” to indicate the method used to obtain the partial result. Then run this method for one more iteration and output in the second line the resulting sequence. It is guaranteed that the answer is unique for each test case. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line.

Sample Input 1:

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

Sample Output 1:

Insertion Sort
1 2 3 5 7 8 9 4 6 0

Sample Input 2:

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

Sample Output 2:

Merge Sort
1 2 3 8 4 5 7 9 0 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>
#include<limits.h>
using namespace std;

int main(void)
{
	int n;
	cin >> n;
	vector<int> num(n);
	vector<int> num2(n);
	vector<int> target(n);
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &num[i]);
	}
	num2 = num;
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &target[i]);
	}
	bool isInsert = false;
	for (int i = 1; i < n; i++)
	{
		int j = i;
		int tmp = num[i];
		for (; j > 0 && num[j - 1] > tmp; j--)
		{
			num[j] = num[j - 1];
		}
		num[j] = tmp;
		if (!isInsert && target == num)
			isInsert=true;
		else if (isInsert)
			break;
	}
	if (isInsert)
	{
		cout << "Insertion Sort" << endl;
		for (int i = 0; i < num.size(); i++)
		{
			cout << num[i];
			if (i != num.size() - 1)
				cout << " ";
		}
		cout << endl;
		return 0;
	}


	bool isMerge = false;
	for (int step = 1; step / 2 < n; step *= 2)
	{//步进初始为1,第二次为2,第三次为4,如此类推
		for (int i = 0; i < n; i += 2 * step)
		{
			vector<int> tmpArr(2 * step);
			int first = i;
			int second = i+step;
			int idx = 0;
			int k = 0;
			while (first<min(n,i+step)||second<min(n,i+2*step))
			{//通过first和second指针,把数组分为两个,然后进行归并排序
				if (first<min(n, i + step) && second<min(n, i + 2 * step))
				{
					if (num2[first] < num2[second])
						tmpArr[idx++] = num2[first++];
					else
						tmpArr[idx++] = num2[second++];
				}
				else if (first<min(n, i + step))//second已经遍历完,剩下first数组
					tmpArr[idx++] = num2[first++];
				else//first已经遍历完,剩下second数组
					tmpArr[idx++] = num2[second++];
			}
			for (int k = 0; k < 2 * step&&i + k < n; k++)
				num2[i + k] = tmpArr[k];
		}
		if (!isMerge&&num2 == target)
			isMerge = true;
		else if (isMerge)
			break;
	}

	cout << "Merge Sort" << endl;
	for (int i = 0; i < num2.size(); i++)
	{
		cout << num2[i];
		if (i != num2.size() - 1)
			cout << " ";
	}
	cout << endl;

	return 0;
}

1088. Rational Arithmetic (20)

1.题目给出两个分数,求这两个分数的四则运算结果。

2.注意在数字和string转化过程中,需要考虑数字不是只有一位的,如300转为“300”,一开始卡在里这里,

测试用例:

24/8 100/10
24/11 300/11

3.该题用到了欧几里德算法求最小公约数gcd(a,b)

算法如下:

//欧几里德算法求最大公约数gcd,其中a>b
long long gcd(long long a, long long b)
{
	return b == 0 ? a : gcd(b, a%b);
}
时间限制
200 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

For two rational numbers, your task is to implement the basic arithmetics, that is, to calculate their sum, difference, product and quotient.

Input Specification:

Each input file contains one test case, which gives in one line the two rational numbers in the format “a1/b1 a2/b2”. The numerators and the denominators are all in the range of long int. If there is a negative sign, it must appear only in front of the numerator. The denominators are guaranteed to be non-zero numbers.

Output Specification:

For each test case, print in 4 lines the sum, difference, product and quotient of the two rational numbers, respectively. The format of each line is “number1 operator number2 = result”. Notice that all the rational numbers must be in their simplest form “k a/b”, where k is the integer part, and a/b is the simplest fraction part. If the number is negative, it must be included in a pair of parentheses. If the denominator in the division is zero, output “Inf” as the result. It is guaranteed that all the output integers are in the range of long int.

Sample Input 1:

2/3 -4/2

Sample Output 1:

2/3 + (-2) = (-1 1/3)
2/3 - (-2) = 2 2/3
2/3 * (-2) = (-1 1/3)
2/3 / (-2) = (-1/3)

Sample Input 2:

5/3 0/6

Sample Output 2:

1 2/3 + 0 = 1 2/3
1 2/3 - 0 = 1 2/3
1 2/3 * 0 = 0
1 2/3 / 0 = Inf

 
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;

/*
24/8 100/10
24/11 300/11
0/0 2/3
*/

//欧几里德算法求最大公约数gcd
long long gcd(long long a, long long b)
{
    return b == 0 ? a : gcd(b, a%b);
}
void str2num(string str, long long&top, long long&bot, int&sign)
{
    bool first = true;
    for (int i = 0; i < str.size(); i++)
    {
        if (str[i] == '-')
            sign = -1;
        else if (str[i] != '/'&&first)
            top = top * 10 + str[i] - '0';
        else if (str[i] == '/')
            first = false;
        else if (str[i] != '/'&&!first)
            bot = bot * 10 + str[i] - '0';
    }
}
string i2s(long long a)
{
    string ans = "";
    if (a == 0) return "0";
    else
    {
        while (a != 0)
        {
            char c = a % 10 + '0';
            ans = c + ans;
            a /= 10;
        }
    }
    return ans;
}
string int2Str(long long top, long long bot, bool sign)
{
    long long tmpGCD = gcd(top, bot);
    top /= tmpGCD;
    bot /= tmpGCD;
    long long tmpInt = top / bot;
    long long tmpRat = top%bot;
    string ans = "";
    if (tmpInt != 0)
    {
        ans = i2s(tmpInt);
    }
    if (tmpRat == 0 && ans.size() != 0)
        ;
    else if (tmpRat == 0 && ans.size() == 0)
    {
        return "0";
    }
    else if (tmpRat != 0 && ans.size() != 0)
    {//整数和分数同时存在
        ans += " "+i2s(tmpRat) + "/" + i2s(bot);
    }
    else if (tmpRat != 0 && ans.size() == 0)
    {//仅存在分数
        ans += i2s(tmpRat) + "/" + i2s(bot);
    }
    if (!sign)
        ans = "(-" + ans + ")";
    return ans;
}
int main(void)
{
    string a, b;
    cin >> a >> b;
    long long aTop = 0, aBot = 0, bTop = 0, bBot = 0;
    int aSign = 1;
    int bSign = 1;
    str2num(a, aTop, aBot, aSign);
    str2num(b, bTop, bBot, bSign);
    string aAns;
    string bAns;
    if (aTop != 0)
    {
        int aGCD = gcd(aTop, aBot);
        aTop /= aGCD;
        aBot /= aGCD;
        aAns = int2Str(aTop, aBot, aSign == 1);
    }
	else
	{
		aAns = "0";
		aBot = 1;
	}
    if (bTop != 0)
    {
        int bGCD = gcd(bTop, bBot);
        bTop /= bGCD;
        bBot /= bGCD;
        bAns = int2Str(bTop, bBot, bSign == 1);
    }
    else
        bAns = "0";
 
    //加法:
    long long addBot = aBot*bBot;
    long long addTop = aSign*aTop*bBot + bSign*bTop*aBot;
    bool addSign = (addTop >= 0 ? true : false);
    addTop = labs(addTop);
    long long addInt = addTop / addBot;
    string addAns = int2Str(addTop, addBot, addSign);
    cout << aAns << " + " << bAns << " = " << addAns << endl;
 
    //减法:
    long long diffBot = aBot*bBot;
    long long diffTop = aSign*aTop*bBot - bSign*bTop*aBot;
    bool diffSign = (diffTop >= 0 ? true : false);
    diffTop = labs(diffTop);
    long long diffInt = diffTop / diffBot;
    string diffAns = int2Str(diffTop, diffBot, diffSign);
    cout << aAns << " - " << bAns << " = " << diffAns << endl;
 
    //乘法
    long long proBot = aBot*bBot;
    long long proTop = aSign*bSign*aTop*bTop;
    bool proSign = (proTop >= 0 ? true : false);
    proTop = labs(proTop);
    long long proInt = proTop / proBot;
    string proAns = int2Str(proTop, proBot, proSign);
    cout << aAns << " * " << bAns << " = " << proAns << endl;
 
 
    //除法
    long long quoBot = aBot*bTop;
    long long quoTop = aSign*bSign*aTop*bBot;
    string quoAns;
    if (quoBot != 0)
    {
        bool quoSign = (quoTop >= 0 ? true : false);
        quoTop = labs(quoTop);
        long long quoInt = quoTop / quoBot;
        quoAns = int2Str(quoTop, quoBot, quoSign);
    }
    else
        quoAns = "Inf";
    cout << aAns << " / " << bAns << " = " << quoAns << endl;
 
    return 0;
}

1087. All Roads Lead to Rome (30)

1.求单源最短路径,如果不唯一,则输出happiness最高的路线。

2.使用dijkstra求出最小耗费,以这个最小耗费作为约束条件,在后面遍历的时候进行剪枝。

1087

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

Indeed there are many different tourist routes from our city to Rome. You are supposed to find your clients the route with the least cost while gaining the most happiness.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 positive integers N (2<=N<=200), the number of cities, and K, the total number of routes between pairs of cities; followed by the name of the starting city. The next N-1 lines each gives the name of a city and an integer that represents the happiness one can gain from that city, except the starting city. Then K lines follow, each describes a route between two cities in the format “City1 City2 Cost”. Here the name of a city is a string of 3 capital English letters, and the destination is always ROM which represents Rome.

Output Specification:

For each test case, we are supposed to find the route with the least cost. If such a route is not unique, the one with the maximum happiness will be recommended. If such a route is still not unique, then we output the one with the maximum average happiness — it is guaranteed by the judge that such a solution exists and is unique.

Hence in the first line of output, you must print 4 numbers: the number of different routes with the least cost, the cost, the happiness, and the average happiness (take the integer part only) of the recommended route. Then in the next line, you are supposed to print the route in the format “City1->City2->…->ROM”.

Sample Input:

6 7 HZH
ROM 100
PKN 40
GDN 55
PRS 95
BLN 80
ROM GDN 1
BLN ROM 1
HZH PKN 1
PRS ROM 2
BLN HZH 2
PKN GDN 1
HZH PRS 1

Sample Output:

3 3 195 97
HZH->PRS->ROM

 
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 cityNode
{
	vector<pair<string, int>> list;
	bool visited;
	bool sured;
	int happiness;
	int cost;
	cityNode() :list(0), visited(false), sured(false), happiness(-1), cost(INT_MAX){};
};

void dfs(string now, int minCost, int nowCost, vector<pair<string, int>>&path, vector<vector<pair<string, int>>>&ans, map<string, bool>&used, map<string, cityNode>&city)
{
	if (now == "ROM"&&nowCost == minCost)
	{
		ans.push_back(path);
	}
	else if (nowCost > minCost)
		return;
	else
	{
		for (int i = 0; i < city[now].list.size(); i++)
		{
			string q = city[now].list[i].first;
			if (!used[q])
			{
				used[q] = true;
				path.push_back({ q, city[q].happiness });
				dfs(q, minCost, nowCost + city[now].list[i].second, path, ans, used, city);
				path.pop_back();
				used[q] = false;
			}
		}
	}
}
bool cmp(const vector<pair<string, int>>&a, const vector<pair<string, int>>&b)
{
	int aHappiness = 0;
	for (int i = 0; i < a.size(); i++)
	{
		aHappiness += a[i].second;
	}
	int bHappiness = 0;
	for (int i = 0; i < b.size(); i++)
	{
		bHappiness += b[i].second;
	}
	if (aHappiness > bHappiness) return true;
	else if (aHappiness == bHappiness && aHappiness / a.size() > bHappiness / b.size())
		return true;
	else return false;
}
int main(void)
{
	int n, k;
	string src;
	cin >> n >> k >> src;
	string target = "ROM";
	map<string, cityNode> city;

	for (int i = 0; i < n - 1; i++)
	{
		string str;
		int happiness;
		cin >> str >> happiness;
		city[str].happiness = happiness;
	}

	for (int i = 0; i < k; i++)
	{
		string a, b;
		int cost;
		cin >> a >> b >> cost;
		city[a].list.push_back({ b, cost });
		city[b].list.push_back({ a, cost });
	}
	city[src].visited = true;
	city[src].cost = 0;
	while (1)
	{
		string p = "";
		for (map<string, cityNode>::iterator ite = city.begin(); ite != city.end(); ite++)
		{
			if (p == ""&&ite->second.visited&&!ite->second.sured)
				p = ite->first;
			else if (p != ""&&ite->second.visited&&!ite->second.sured&& ite->second.cost < city[p].cost)
				p = ite->first;
		}
		if (p == "") break;
		city[p].sured = true;
		if (city[target].sured) break;
		for (int i = 0; i < city[p].list.size(); i++)
		{
			string q = city[p].list[i].first;
			if (!city[q].sured&&city[p].cost + city[p].list[i].second < city[q].cost)
			{
				city[q].visited = true;
				city[q].cost = city[p].cost + city[p].list[i].second;
			}
		}
	}
	int minCost = city[target].cost;

	map<string, bool> used;
	vector<pair<string, int>>path;
	vector<vector<pair<string, int>>>ans;
	dfs(src, minCost, 0, path, ans, used, city);
	sort(ans.begin(), ans.end(), cmp);
	int totalHappiness = 0;
	int avgHappiness = 0;
	for (int i = 0; i < ans[0].size(); i++)
	{
		totalHappiness += ans[0][i].second;
	}
	avgHappiness = totalHappiness / ans[0].size();
	printf("%d %d %d %d\n", ans.size(), minCost, totalHappiness, avgHappiness);
	cout << src << "->";
	for (int i = 0; i < ans[0].size(); i++)
	{
		cout << ans[0][i].first;
		if (i != ans[0].size() - 1)
			cout << "->";
	}
	cout << endl;
	return 0;
}

1086. Tree Traversals Again (25)

1.重点!题目给出用栈进行中序遍历的操作,要求还原二叉树,并层序遍历。

2.如果上次没有弹出,并且栈为空,则这次压入的为根。

3.如果上次有弹出,并且这次压入,那么上次弹出的是父节点,这次压入的是右子节点。

4.如果上次没有弹出,并且这次压入,那么这次压入的是栈头的左子节点。

5.每次弹出一个节点,都要把这个节点记录下来,lastPop。

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

An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For example, suppose that when a 6-node binary tree (with the keys numbered from 1 to 6) is traversed, the stack operations are: push(1); push(2); push(3); pop(); pop(); push(4); pop(); pop(); push(5); push(6); pop(); pop(). Then a unique binary tree (shown in Figure 1) can be generated from this sequence of operations. Your task is to give the postorder traversal sequence of this tree.

1086Figure 1
Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<=30) which is the total number of nodes in a tree (and hence the nodes are numbered from 1 to N). Then 2N lines follow, each describes a stack operation in the format: “Push X” where X is the index of the node being pushed onto the stack; or “Pop” meaning to pop one node from the stack.

Output Specification:

For each test case, print the postorder traversal sequence of the corresponding tree in one line. A solution is guaranteed to exist. All the numbers must be separated by exactly one space, and there must be no extra space at the end of the line.

Sample Input:

6
Push 1
Push 2
Push 3
Pop
Pop
Push 4
Pop
Pop
Push 5
Push 6
Pop
Pop

Sample Output:

3 4 2 6 5 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;
struct TreeNode
{
	int val;
	TreeNode*l, *r;
	TreeNode() :val(-1), l(NULL), r(NULL){};
	TreeNode(int x) :val(x), l(NULL), r(NULL){};
};
void InOrder(TreeNode*root, vector<int>&in)
{
	if (root)
	{
		InOrder(root->l, in);
		InOrder(root->r, in);
		in.push_back(root->val);
	}
}
int main(void)
{
	stack<TreeNode*> sta;
	TreeNode*root = NULL;
	TreeNode*lastPop = NULL;
	int n;
	cin >> n;
	for (int i = 0; i < 2 * n; i++)
	{
		string str;
		cin >> str;
		if (str == "Push")
		{
			int tmp;
			cin >> tmp;
			if (sta.empty() && lastPop == NULL)
			{
				root = new TreeNode(tmp);
				sta.push(root);
			}
			else if (lastPop)
			{//如果上次pop出了,这次压入,证明是右子树
				lastPop->r = new TreeNode(tmp);
				sta.push(lastPop->r);
			}
			else
			{
				sta.top()->l = new TreeNode(tmp);
				sta.push(sta.top()->l);
			}
			lastPop = NULL;//这次是压入,所以没有上次Pop出的元素的值
		}
		else
		{//这次是pop出,所以需要存储pop出的元素
			TreeNode*head = sta.top();
			sta.pop();
			lastPop = head;
		}
	}
	vector<int> in(0);
	InOrder(root, in);
	for (int i = 0; i < in.size(); i++)
	{
		cout << in[i];
		if (i != in.size() - 1)
			cout << " ";
	}
	cout << endl;
	return 0;
}

1085. Perfect Sequence (25)

1.找出满足M <= m * p要求的最长子序列,其中M为子序列里面的最大值,m为最小值。

2.先对输入的数据进行排序。

3.开始遍历所有情况,其中i从0开始遍历,求得j,使得num[j]<=num[i]*p,用二分法去查找j,把满足情况的都个数记录并取最大值。

4.不用二分法的话,第5个测试点会超时。

5.使用long long存储数据,后续的比较中,因为p<=10^9,num的最大值可以是10^9,超过32位int型,需要使用long long,才能通过最后一个测试点。

1085

 

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

Given a sequence of positive integers and another positive integer p. The sequence is said to be a “perfect sequence” if M <= m * p where M and m are the maximum and minimum numbers in the sequence, respectively.

Now given a sequence and a parameter p, you are supposed to find from the sequence as many numbers as possible to form a perfect subsequence.

Input Specification:

Each input file contains one test case. For each case, the first line contains two positive integers N and p, where N (<= 105) is the number of integers in the sequence, and p (<= 109) is the parameter. In the second line there are N positive integers, each is no greater than 109.

Output Specification:

For each test case, print in one line the maximum number of integers that can be chosen to form a perfect subsequence.

Sample Input:

10 8
2 3 20 4 5 1 6 7 8 9

Sample Output:

8

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>
using namespace std;
/*
7 10
1 10 11 12 13 14 15

10 8
2 3 20 4 5 1 6 7 8 9

2 1
2 3

10 0
2 3 20 4 5 1 6 7 8 9
*/
int main(void)
{
	int n, p;
	cin >> n >> p;
	vector<long long> num(n);
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &num[i]);
	}
	int maxSize = 0;
	sort(num.begin(), num.end());
	for (int i = 0; i < n; i++)
	{//从i=0开始遍历
		long long tmp = num[i] * p;
		int l = i;
		int r = n - 1;
		while (l <= r)
		{//采用二分法查找
			int mid = (l + r) / 2;
			if (num[mid] <= tmp)
			{
				l = mid + 1;
				maxSize = max(maxSize, mid + 1 - i);//满足情况的数值都进行比较
			}
			else
			{
				r = mid - 1;
			}
		}
	}
	cout << maxSize << endl;
	return 0;
}

1084. Broken Keyboard (20)

1.给出两个字符串,其中第二个有部分字符打不错来,求出这些缺失的字符。

2.注意哈希表里面大小写字母需要一致,即如果a出现了,那么A也标记为出现了,如果A出现了,那么a也标记为出现了。

1084

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

On a broken keyboard, some of the keys are worn out. So when you type some sentences, the characters corresponding to those keys will not appear on screen.

Now given a string that you are supposed to type, and the string that you actually type out, please list those keys which are for sure worn out.

Input Specification:

Each input file contains one test case. For each case, the 1st line contains the original string, and the 2nd line contains the typed-out string. Each string contains no more than 80 characters which are either English letters [A-Z] (case insensitive), digital numbers [0-9], or “_” (representing the space). It is guaranteed that both strings are non-empty.

Output Specification:

For each test case, print in one line the keys that are worn out, in the order of being detected. The English letters must be capitalized. Each worn out key must be printed once only. It is guaranteed that there is at least one worn out key.

Sample Input:

7_This_is_a_test
_hs_s_a_es

Sample Output:

7TI

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>
using namespace std;
/*
7_This_is_a_test
_hs_s_a_es
 
7_This_is_a_test
7
*/
int main(void)
{
    string s1, s2;
    cin >> s1 >> s2;
    vector<bool> m(500, 0);
    for (int i = 0; i < s2.size(); i++)
    {
        m[s2[i] + 128] = true;
    }
    string ans = "";
    for (int i = 0; i < s1.size(); i++)
    {
        if (!m[s1[i] + 128] )
        {
            m[s1[i] + 128] = true;
            char c = s1[i];
            if (c >= 'A'&&c <= 'Z')
            {
                c = c - 'A' + 'a';
                m[c+ 128] = true;//小写后的字母也要true
            }
            if (c >= 'a'&&c <= 'z')
                c = c - 'a' + 'A';
            m[c+ 128] = true;//大写后的字母也要true
            ans += c;
        }
    }
    cout << ans << endl;
     
    return 0;
}

1083. List Grades (25)

1.题目要求根据一定的分数范围,对学生进行排序输出。

2.题目提到各个同学的分数是唯一的,所以可以采用分数作为下标,直接建立101个学生节点,即0~100分。

3.然后根据最高分限制和最低分限制,筛选出学生进行输出。

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

Given a list of N student records with name, ID and grade. You are supposed to sort the records with respect to the grade in non-increasing order, and output those student records of which the grades are in a given interval.

Input Specification:

Each input file contains one test case. Each case is given in the following format:

N
name[1] ID[1] grade[1]
name[2] ID[2] grade[2]
... ...
name[N] ID[N] grade[N]
grade1 grade2

where name[i] and ID[i] are strings of no more than 10 characters with no space, grade[i] is an integer in [0, 100], grade1 and grade2 are the boundaries of the grade’s interval. It is guaranteed that all the grades are distinct.

Output Specification:

For each test case you should output the student records of which the grades are in the given interval [grade1, grade2] and are in non-increasing order. Each student record occupies a line with the student’s name and ID, separated by one space. If there is no student’s grade in that interval, output “NONE” instead.

Sample Input 1:

4
Tom CS000001 59
Joe Math990112 89
Mike CS991301 100
Mary EE990830 95
60 100

Sample Output 1:

Mike CS991301
Mary EE990830
Joe Math990112

Sample Input 2:

2
Jean AA980920 60
Ann CS01 80
90 95

Sample Output 2:

NONE

 
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 StudentNode{
	string id, name;
	StudentNode() :id(""), name(""){};
};
int main(void)
{
	vector<StudentNode> student(101);
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		int grade;
		string name, id;
		cin >> name >> id >> grade;
		student[grade].name = name;
		student[grade].id = id;
	}
	int minGrade , maxGrade;
	cin >> minGrade >> maxGrade;
	vector<StudentNode> ans(0);
	for (int i = maxGrade; i >= minGrade; i--)
	{
		if (student[i].name!="")
		{
			ans.push_back(student[i]);
		}
	}

	if (ans.size() == 0)
		cout << "NONE" << endl;
	else
	{
		for (int i = 0; i < ans.size(); i++)
			cout << ans[i].name << " " << ans[i].id << endl;
	}

	return 0;
}

1082. Read Number in Chinese (25)

1.把一串数字按照中文的习惯进行转换。

1.需要分类考虑的情况比较多

2.123456789可以分为 1  2345  6789   ,其中2345和6789的处理方法相同,不同点就是2345处理完后需要加上Wan

3.需要处理0等特殊情况

4下面有些特别的测试例子,可以参考:


/*
-123456789
123400000
123000000
120000000
100000000
123000010
-23456789
23400000
23000000
20000000
00000000
23000010
*/

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

Given an integer with no more than 9 digits, you are supposed to read it in the traditional Chinese way. Output “Fu” first if it is negative. For example, -123456789 is read as “Fu yi Yi er Qian san Bai si Shi wu Wan liu Qian qi Bai ba Shi jiu”. Note: zero (“ling”) must be handled correctly according to the Chinese tradition. For example, 100800 is “yi Shi Wan ling ba Bai”.

Input Specification:

Each input file contains one test case, which gives an integer with no more than 9 digits.

Output Specification:

For each test case, print in a line the Chinese way of reading the number. The characters are separated by a space and there must be no extra space at the end of the line.

Sample Input 1:

-123456789

Sample Output 1:

Fu yi Yi er Qian san Bai si Shi wu Wan liu Qian qi Bai ba Shi jiu

Sample Input 2:

100800

Sample Output 2:

yi Shi Wan ling ba Bai

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;
/*
-123456789
123400000
123000000
120000000
100000000
123000010
-23456789
23400000
23000000
20000000
00000000
23000010
-7005

-90000
*/
string num2Chinese[] = { "ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu" };
string deleteZero(string str)
{
	string tmp = "";
	bool firstZero = true;
	for (int i = 0; i < str.size(); i++)
	{
		if (str[i] == '0'&&firstZero)
			;
		else
		{
			firstZero = false;
			tmp += str[i];
		}
	}
	return tmp;
}
string digit1(string str)
{//只有一位数字的时候
	if (str == "") return str;
	else return num2Chinese[str[0] - '0'];
}
string digit2(string str)
{//两位数组,10为yi Shi,11为yi Shi yi,处理这两种特殊情况:1)个位为0:2)各位不为0
	string strTmp = num2Chinese[str[0] - '0'] + " Shi";
	string next = deleteZero(str.substr(1));
	if (next.size() == 1)
		return strTmp + " " + digit1(next);
	else return strTmp;
}
string digit3(string str)
{//100,101,110,111处理三种特殊情况,1)十位不为0;2)十位为0,个位不为0;3)十位、个位均为0
	string strTmp = num2Chinese[str[0] - '0'] + " Bai";
	string next = deleteZero(str.substr(1));
	if (next.size() == 2)
		return strTmp + " " + digit2(next);
	else if (next.size() == 1)
		return strTmp + " ling " + digit1(next);
	else return strTmp;
}
string digit4(string str)
{//1000,1001,1011,1111处理四种特殊情况,1)百位不为0;2)百位为0,十位不为0,个位不为0;3)百位、十位均为0,个位不为0;4)百位、十位、个位均为0
	string strTmp = num2Chinese[str[0] - '0'] + " Qian";
	string next = deleteZero(str.substr(1));
	if (next.size() == 3)
		return strTmp + " " + digit3(next);
	else if (next.size() == 2)
	{
		return strTmp + " ling " + digit2(next);
	}
	else if (next.size() == 1)
	{
		return strTmp + " ling " + digit1(next);
	}
	else return strTmp;
}
string digitProc(string str)
{
	switch (str.size())
	{
	case 0:return digit1(str);
	case 1:return digit1(str);
	case 2:return digit2(str);
	case 3:return digit3(str);
	case 4:return digit4(str);
	default:
		return "";
	}
}

int main(void)
{
	string str;
	cin >> str;
	bool sign = true;
	if (str[0] == '-')
	{
		sign = false;
		str = str.substr(1);
	}
	str = deleteZero(str);
	string ans = "";
	if (str.size() == 9)
	{//包括亿位
		string a = str.substr(0, 1);
		string b = str.substr(1, 4);
		string c = str.substr(5, 4);
		ans = num2Chinese[a[0] - '0'] + " Yi";
		string tmpB = deleteZero(b);
		string tmpC = deleteZero(c);
		if (tmpB.size() == 4 && tmpC.size() == 4)
			ans += " " + digitProc(tmpB) + " Wan " + digitProc(tmpC);
		else if (tmpB.size() == 4 && tmpC.size() == 0)
			ans += " " + digitProc(tmpB) + " Wan ";
		else if (tmpB.size() == 4 && tmpC.size() < 4)
			ans += " " + digitProc(tmpB) + " Wan ling " + digitProc(tmpC);
		else if (tmpB.size() == 0 && tmpC.size() == 0)
			;
		else if (tmpB.size() == 0 && tmpC.size() <= 4)
			ans += " ling " + digitProc(tmpC);
		else if (tmpB.size() < 4 && tmpC.size() == 0)
			ans += " ling" + digitProc(tmpB) + " Wan ";
	}
	else if (str.size() < 9 && str.size() > 4)
	{//不包括亿位,包括万位
		string b = str.substr(0, str.size() - 4);
		string c = str.substr(str.size() - 4);
		string tmpB = deleteZero(b);
		string tmpC = deleteZero(c);
		if (tmpB.size() == b.size() && tmpC.size() == c.size())
			ans += digitProc(tmpB) + " Wan " + digitProc(tmpC);
		else if (tmpB.size() == 0 && tmpC.size() == 0)
			;
		else if (tmpB.size() == 0 && tmpC.size() <= 4)
			ans += digitProc(tmpC);
		else if (tmpB.size() == 4 && tmpC.size() == 0)
			ans += digitProc(tmpB) + " Wan";
		else if (tmpB.size() < 4 && tmpC.size() == 0)
			ans += digitProc(tmpB) + " Wan";
		else if (tmpB.size() < 4 && tmpC.size() < 4)
			ans += digitProc(tmpB) + " Wan ling " + digitProc(tmpC);
		else if (tmpB.size() == 4 && tmpC.size() < 4)
			ans += digitProc(tmpB) + " Wan ling " + digitProc(tmpC);
	}
	else if (str.size() <= 4 && str.size() != 0)
	{
		ans = digitProc(str);
	}
	else if (str.size() == 0)
		ans = "ling";
	if (!sign)
		ans = "Fu " + ans;
	cout << ans <<endl;

	return 0;
}

1081. Rational Sum (20)

1.题目要求求一串分数相加的结果。

2.每次读取一个数时,对其进行因式化简,再累加,需要用到欧几里德算法

3.每次直接进行相加,分子先不对分母取模,在最后才进行取模,才把整数部分提取出来。

4.注意在计算gcd时,取bot和top的绝对值,避免算出来的gcd为-1,使得top和bot的符号翻转。

5.刚开始尝试使用scanf(“%d/%d”,&a,&b)进行分式的读取,结果在读取负数分式的时候出错,所以改为读取string,然后再进行解析。

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

Given N rational numbers in the form “numerator/denominator”, you are supposed to calculate their sum.

Input Specification:

Each input file contains one test case. Each case starts with a positive integer N (<=100), followed in the next line N rational numbers “a1/b1 a2/b2 …” where all the numerators and denominators are in the range of “long int”. If there is a negative number, then the sign must appear in front of the numerator.

Output Specification:

For each test case, output the sum in the simplest form “integer numerator/denominator” where “integer” is the integer part of the sum, “numerator” < “denominator”, and the numerator and the denominator have no common factor. You must output only the fractional part if the integer part is 0.

Sample Input 1:

5
2/5 4/15 1/30 -2/60 8/3

Sample Output 1:

3 1/3

Sample Input 2:

2
4/3 2/3

Sample Output 2:

2

Sample Input 3:

3
1/3 -1/6 1/8

Sample Output 3:

7/24

 
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;
/*
3
1/3 -1/6 1/8

3
0/1 0/2 0/3

3
-1/2 -3/2 -1/3

4
-1/2 -3/2 -1/3 1/3

4
1/2 3/2 -1/3 1/3

4
1/2 3/2 -1/2 -3/2
*/
long long gcd(long long a, long long b)
{
	return (b == 0 ? a : gcd(b, a%b));
}
struct ratNode{
	long long top;
	long long bot;
	ratNode(int a, int b) :top(a), bot(b){};
	ratNode() :top(0), bot(1){};

};
void add2Num(long long&nowTop, long long&nowBot, long long nextTop, long long nextBot)
{
	long long botGCD = gcd(nowBot, nextBot);
	long long a = nextBot / botGCD;
	long long b = nowBot / botGCD;
	long long top = nowTop*a + nextTop*b;
	long long bot = a*nowBot;
	long long GCD = gcd(labs(top), labs(bot));//注意取绝对值,避免算出来的gcd为-1,使得top和bot的符号翻转
	nowTop = top / GCD;
	nowBot = bot / GCD;
}
void str2num(string str, long long&top, long long&bot)
{
	bool sign = true;
	bool first = true;
	top = 0; bot = 0;
	for (int i = 0; i < str.size(); i++)
	{
		if (str[i] == '-')
			sign = false;
		else if (str[i] == '/')
			first = false;
		else if (first)
			top = top * 10 + str[i] - '0';
		else if (!first)
			bot = bot * 10 + str[i] - '0';
	}
	if (!sign) top = -top;
}
int main(void)
{
	int n;
	cin >> n;
	vector<ratNode> rat(n);
	long long nowTop = 0;
	long long nowBot = 1;
	for (int i = 0; i < n; i++)
	{
		string str;
		cin >> str;
		str2num(str, rat[i].top, rat[i].bot);
		if (rat[i].top == 0) rat[i].bot = 1;
		int GCD = gcd(labs(rat[i].top), labs(rat[i].bot));//注意取绝对值,避免算出来的gcd为-1,使得top和bot的符号翻转
		rat[i].top /= GCD;
		rat[i].bot /= GCD;
		add2Num(nowTop, nowBot, rat[i].top, rat[i].bot);
	}

	long long nowInt = nowTop / nowBot;
	nowTop = nowTop - (nowInt*nowBot);
	if (nowTop < 0 && nowInt!=0 ) nowTop = -nowTop;

	if (nowTop == 0 && nowInt==0)
		cout << "0" << endl;
	else if (nowTop == 0)
		cout << nowInt << endl;
	else if (nowInt == 0)
		cout << nowTop << "/" << nowBot << endl;
	else 
		cout << nowInt << " " << nowTop << "/" << nowBot << endl;

	return 0;
}