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

1080. Graduate Admission (30)

1.题目模拟学校录取学生的情况。

2.注意排名,在总分数和各个分数相同的情况下,排名必须相同。

3.注意录取,学校记录一个最后录取学生的排名,当学校没有名额后,判断这个排名和当前申请的学生排名是否相等,如果相等,则必须录取这个学生。

20151124185158330

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

It is said that in 2013, there were about 100 graduate schools ready to proceed over 40,000 applications in Zhejiang Province. It would help a lot if you could write a program to automate the admission procedure.

Each applicant will have to provide two grades: the national entrance exam grade GE, and the interview grade GI. The final grade of an applicant is (GE + GI) / 2. The admission rules are:

  • The applicants are ranked according to their final grades, and will be admitted one by one from the top of the rank list.
  • If there is a tied final grade, the applicants will be ranked according to their national entrance exam grade GE. If still tied, their ranks must be the same.
  • Each applicant may have K choices and the admission will be done according to his/her choices: if according to the rank list, it is one’s turn to be admitted; and if the quota of one’s most preferred shcool is not exceeded, then one will be admitted to this school, or one’s other choices will be considered one by one in order. If one gets rejected by all of preferred schools, then this unfortunate applicant will be rejected.
  • If there is a tied rank, and if the corresponding applicants are applying to the same school, then that school must admit all the applicants with the same rank, even if its quota will be exceeded.

Input Specification:

Each input file contains one test case. Each case starts with a line containing three positive integers: N (<=40,000), the total number of applicants; M (<=100), the total number of graduate schools; and K (<=5), the number of choices an applicant may have.

In the next line, separated by a space, there are M positive integers. The i-th integer is the quota of the i-th graduate school respectively.

Then N lines follow, each contains 2+K integers separated by a space. The first 2 integers are the applicant’s GE and GI, respectively. The next K integers represent the preferred schools. For the sake of simplicity, we assume that the schools are numbered from 0 to M-1, and the applicants are numbered from 0 to N-1.

Output Specification:

For each test case you should output the admission results for all the graduate schools. The results of each school must occupy a line, which contains the applicants’ numbers that school admits. The numbers must be in increasing order and be separated by a space. There must be no extra space at the end of each line. If no applicant is admitted by a school, you must output an empty line correspondingly.

Sample Input:

11 6 3
2 1 2 2 2 3
100 100 0 1 2
60 60 2 3 5
100 90 0 3 4
90 100 1 2 0
90 90 5 1 3
80 90 1 0 2
80 80 0 1 2
80 80 0 1 2
80 70 1 3 2
70 80 1 2 3
100 100 0 2 4

Sample Output:

0 10
3
5 6 7
2 8

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;

struct StudentNode{
	int Ge, Gi;
	int totalGrade;
	int rank;
	int id;
	vector<int> choice;
	StudentNode() :Ge(0), Gi(0), totalGrade(0), rank(-1), id(-1), choice(0){};
	StudentNode(int x) :Ge(0), Gi(0), totalGrade(0), rank(-1), id(-1), choice(vector<int>(x,0)){};
};
struct SchoolNode{
	int quato;
	int lastRank;
	vector<int> student;
	SchoolNode() :quato(0), lastRank(0), student(0){};
};
bool cmp(const StudentNode&a, const StudentNode&b)
{
	if (a.totalGrade > b.totalGrade)
		return true;
	else if (a.totalGrade == b.totalGrade && a.Ge > b.Ge)
		return true;
	else return false;
}
int main(void)
{
	int studentSum, schoolSum, choiceSum;
	cin >> studentSum >> schoolSum >> choiceSum;
	vector<StudentNode> student(studentSum, StudentNode(choiceSum));
	vector<SchoolNode> school(schoolSum);

	for (int i = 0; i < school.size(); i++)
	{//输入每个学校的招生名额
		scanf("%d", &school[i].quato);
	}

	for (int i = 0; i < student.size(); i++)
	{//输入学生信息
		scanf("%d %d", &student[i].Ge, &student[i].Gi);
		for (int j = 0; j < choiceSum; j++)
		{//输入志愿
			scanf("%d", &student[i].choice[j]);
		}
		student[i].totalGrade = student[i].Ge + student[i].Gi;
		student[i].id = i;
	}

	sort(student.begin(), student.end(), cmp);
	student[0].rank = 0;
	for (int i = 1; i < student.size(); i++)
	{//统计学生的排名
		if (student[i].totalGrade == student[i - 1].totalGrade && student[i].Ge == student[i - 1].Ge)
			student[i].rank = student[i - 1].rank;//所有成绩相等的学生排名一样
		else
			student[i].rank = i;
	}

	for (int i = 0; i < student.size(); i++)
	{
		for (int j = 0; j < student[i].choice.size(); j++)
		{
			int num = student[i].choice[j];
			if (school[num].quato > 0 || (school[num].quato == 0 && school[num].lastRank == student[i].rank))
			{//还有名额,或者,没有名额但是学校招收的最后一名的排名和当前学生排名一样,需要同样招收
				if (school[num].quato>0)
					school[num].quato--;
				school[num].lastRank = student[i].rank;//更新学校招收学生的排名
				school[num].student.push_back(student[i].id);//压入学生的id
				break;//学生被录取了,不再遍历后面的志愿
			}
		}
	}
	for (int i = 0; i < school.size(); i++)
	{
		sort(school[i].student.begin(), school[i].student.end());//对学生的id进行排序
		for (int j = 0; j < school[i].student.size(); j++)
		{
			printf("%d", school[i].student[j]);
			if (j != school[i].student.size() - 1)
				printf(" ");
		}
		printf("\n");
	}

	return 0;
}