1066. Root of AVL Tree (25)

1.题目给出一个数组,要求逐个输入后,输出AVL树的根。

2.这道题比较重要,主要考察AVL树的建立。

3.需要掌握单旋转,双旋转,插入等操作。

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

An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. Figures 1-4 illustrate the rotation rules.

1066

Now given a sequence of insertions, you are supposed to tell the root of the resulting AVL tree.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<=20) which is the total number of keys to be inserted. Then N distinct integer keys are given in the next line. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print ythe root of the resulting AVL tree in one line.

Sample Input 1:

5
88 70 61 96 120

Sample Output 1:

70

Sample Input 2:

7
88 70 61 96 120 90 65

Sample Output 2:

88

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;
/*
5
88 70 61 96 120

7
88 70 61 96 120 95 65
*/
struct AvlNode{
	int val, height;
	AvlNode*l, *r;
	AvlNode() :val(-1), height(-1), l(NULL), r(NULL){};
	AvlNode(int x) :val(x), height(0), l(NULL), r(NULL){};
};
static int Height(AvlNode* T)
{
	if (T == NULL) return -1;
	else return T->height;
}
static AvlNode* SingleRotateLeft(AvlNode* k2)
{
	AvlNode*k1 = k2->l;
	k2->l = k1->r;
	k1->r = k2;
	k2->height = max(Height(k2->l), Height(k2->r)) + 1;
	k1->height = max(Height(k1->l), k2->height) + 1;
	return k1;
}
static AvlNode* SingleRotateRight(AvlNode* k1)
{
	AvlNode*k2 = k1->r;
	k1->r = k2->l;
	k2->l = k1;
	k1->height = max(Height(k1->l), Height(k1->r)) + 1;
	k2->height = max(Height(k2->r), k1->height) + 1;
	return k2;
}
static AvlNode* DoubleRotateLeft(AvlNode* k3)
{
	k3->l = SingleRotateRight(k3->l);
	return SingleRotateLeft(k3);
}

static AvlNode* DoubleRotateRight(AvlNode* k3)
{
	k3->r = SingleRotateLeft(k3->r);
	return SingleRotateRight(k3);
}

static AvlNode* Insert(int x, AvlNode*T)
{
	if (T == NULL)
		T = new AvlNode(x);
	else if (x < T->val)
	{
		T->l = Insert(x, T->l);
		if (Height(T->l) - Height(T->r) == 2)
		{
			if (x < T->l->val)
				T = SingleRotateLeft(T);
			else
				T = DoubleRotateLeft(T);
		}
	}
	else if (x > T->val)
	{
		T->r = Insert(x, T->r);
		if (Height(T->r) - Height(T->l) == 2)
		{
			if (x>T->r->val)
				T = SingleRotateRight(T);
			else
				T = DoubleRotateRight(T);
		}
	}
	T->height = max(Height(T->l), Height(T->r)) + 1;
	return T;
}
int main(void)
{
	int n;
	cin >> n;
	AvlNode* root = NULL;
	for (int i = 0; i < n; i++)
	{
		int tmp;
		cin >> tmp;
		root=Insert(tmp, root);
	}
	cout << root->val << endl;
	return 0;
}

1065. A+B and C (64bit) (20)

1.题目给出三个数a,b,c,要求判断a+b是否等于c。

2.使用string读取a和b,如果符号相同,按照字符串来处理,因为两个负数或者两个正数相加,会超过最大的取值范围。

3.如果符号不同,那么a+b一定会在范围内,可以使用long long进行处理和比。

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

Given three integers A, B and C in [-263, 263], you are supposed to tell whether A+B > C.

Input Specification:

The first line of the input gives the positive number of test cases, T (<=10). Then T test cases follow, each consists of a single line containing three integers A, B and C, separated by single spaces.

Output Specification:

For each test case, output in one line “Case #X: true” if A+B>C, or “Case #X: false” otherwise, where X is the case number (starting from 1).

Sample Input:

3
1 2 3
2 3 4
9223372036854775807 -9223372036854775808 0

Sample Output:

Case #1: false
Case #2: true
Case #3: false

 
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;
/*
1000
9223372036854775807 -9223372036854775808 0
9223372036854775807 -9223372036854775806 0
9223372036854775808 -9223372036854775807 1
9223372036854775808 -9223372036854775807 2
1 1 0
1 1 2
1 1 3
-1 -1 0
-1 -1 -2
-1 -1 -3
*/
long long str2long(string a)
{
	long long ans = 0;
	for (int i = 0; i < a.size(); i++)
		ans = ans * 10 + a[i] - '0';
	return ans;
}
string reverseStr(string a)
{
	for (int i = 0; i < a.size() / 2; i++)
		swap(a[i], a[a.size() - 1 - i]);
	return a;
}

int main(void)
{
	int n;
	cin >> n;
	for (int k = 0; k < n;k++)
	{
		bool isBigger = true;
		string a, b;
		cin >> a >> b;
		bool aPositive = false;
		bool bPositive = false;
		//如果是负数,则进行标记和去掉负号
		if (a[0] == '-')
		{
			a = a.substr(1);
			aPositive = true;
		}
		if (b[0] == '-')
		{
			b = b.substr(1);
			bPositive = true;
		}
		if ((aPositive&&bPositive) || (!aPositive&&!bPositive))
		{
			string ans = "";
			if (a.size() > b.size()) swap(a, b);//保证a最短
			a = reverseStr(a);
			b = reverseStr(b);
			int i = 0;
			int carry = 0;
			for (; i < a.size(); i++)
			{
				int sum = a[i] - '0' + b[i] - '0' + carry;
				carry = sum / 10;
				char c = sum % 10 + '0';
				ans = c + ans;
			}

			for (; i < b.size(); i++)
			{
				int sum = b[i] - '0' + carry;
				carry = sum / 10;
				char c = sum % 10 + '0';
				ans = c + ans;
			}
			if (carry != 0)
			{
				char c = carry + '0';
				ans = c + ans;
			}
			
			//输入c
			string c;
			cin >> c;
			bool cPositive = false;
			if (c[0] == '-')
			{
				c = c.substr(1);
				cPositive = true;
			}
			if (aPositive&&bPositive && cPositive)
			{//a+b为负数,c为负数
				if (ans.size() > c.size())//a+b的绝对值大于c的绝对值
					isBigger = false;
				else if (ans.size() == c.size())
				{
					for (int i = 0; i < ans.size(); i++)
					{
						if (ans[i]>c[i])
						{//a+b的绝对值大于c的绝对值
							isBigger = false;
							break;
						}
						else if (ans[i] < c[i])
						{//a+b的绝对值小于c的绝对值
							isBigger = true;
							break;
						}
					}
					if (ans == c) isBigger = false;//相等的话,为false
				}
				else
					isBigger = true;
			}
			else if (aPositive&&bPositive && !cPositive)
			{//a+b为负数,c为正数
				isBigger = false;
			}
			else if (!aPositive&&!bPositive && cPositive)
			{//a+b为正数,c为负数
				isBigger = true;
			}
			else
			{//a+b为正数,c为正数
				if (ans.size() > c.size())//a+b的绝对值大于c的绝对值
					isBigger = true;
				else if (ans.size() == c.size())
				{
					for (int i = 0; i < ans.size(); i++)
					{
						if (ans[i]>c[i])
						{//a+b的绝对值大于c的绝对值
							isBigger = true;
							break;
						}
						else if (ans[i] < c[i])
						{//a+b的绝对值小于c的绝对值
							isBigger = false;
							break;
						}
					}
					if (ans == c) isBigger = false;//相等的话,为false
				}
				else
					isBigger = false;
			}
		}
		else
		{
			long long aInt = str2long(a), bInt = str2long(b);
			long long ans;
			if (!aPositive&&bPositive)
				ans = aInt - bInt;
			else
				ans = bInt - aInt;
			long long c;
			cin >> c;
			if (ans > c)
				isBigger = true;
			else isBigger = false;
		}

		if (isBigger)
			printf("Case #%d: true\n", k + 1);
		else
			printf("Case #%d: false\n", k + 1);
	}
	return 0;
}

1064. Complete Binary Search Tree (30)

1.题目给出一个数组,要求构成完全的BST。

2.建立一个n节点的 完全二叉树,然后使用中序遍历,把地址数组遍历出来,再填充数组。

3.注意读取的数组需要先排序,在填充到完全二叉树的中序遍历数组中。

1064

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

A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:

  • The left subtree of a node contains only nodes with keys less than the node’s key.
  • The right subtree of a node contains only nodes with keys greater than or equal to the node’s key.
  • Both the left and right subtrees must also be binary search trees.

A Complete Binary Tree (CBT) is a tree that is completely filled, with the possible exception of the bottom level, which is filled from left to right.

Now given a sequence of distinct non-negative integer keys, a unique BST can be constructed if it is required that the tree must also be a CBT. You are supposed to output the level order traversal sequence of this BST.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<=1000). Then N distinct non-negative integer keys are given in the next line. All the numbers in a line are separated by a space and are no greater than 2000.

Output Specification:

For each test case, print in one line the level order traversal sequence of the corresponding complete binary search tree. 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:

10
1 2 3 4 5 6 7 8 9 0

Sample Output:

6 3 8 1 5 7 9 0 2 4

 
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;
struct TreeNode{
	int val;
	TreeNode*l, *r;
	TreeNode() :val(-1), l(NULL), r(NULL){};
};
void inOrder(TreeNode*root, vector<TreeNode*>&ans)
{
	if (root != NULL)
	{
		inOrder(root->l, ans);
		ans.push_back(root);
		inOrder(root->r, ans);
	}
}
int main(void)
{
	int n;
	cin >> n;
	if (n == 0)
	{
		cout << endl;
		return 0;
	}
	vector<TreeNode> tree(n);
	queue<TreeNode*> q;
	int idx = 0;
	q.push(&tree[idx++]);
	int count1 = 1;
	int count2 = 0;
	//建立一棵节点数为n的完全二叉树
	while (idx < n)
	{
		for (int i = 0; i < count1; i++)
		{
			TreeNode*head = q.front();
			q.pop();
			head->l = &tree[idx++];
			q.push(head->l);
			count2++;
			if (idx == n)
				break;
			head->r = &tree[idx++];
			q.push(head->r);
			count2++;
			if (idx == n)
				break;
		}
		count1 = count2;
		count2 = 0;
	}

	//把树按照中序遍历出一个数组,然后填充数值,主要读取的数组要先排序
	vector<TreeNode*> in(0);
	inOrder(&tree[0], in);
	vector<int> num(n);
	for (int i = 0; i < in.size(); i++)
	{
		scanf("%d", &num[i]);
	}
	sort(num.begin(), num.end());
	for (int i = 0; i < in.size(); i++)
	{
		in[i]->val = num[i];
	}

	queue<TreeNode*> bfs;
	bfs.push(&tree[0]);
	count1 = 1;
	count2 = 0;
	vector<int> ans(0);
	int idxOut = 0;
	while (!bfs.empty())
	{
		for (int i = 0; i < count1; i++)
		{
			TreeNode*head = bfs.front();
			bfs.pop();
			if (idxOut == 0)
				printf("%d", head->val);
			else
				printf(" %d", head->val);
			idxOut++;
			if (head->l != NULL)
			{
				bfs.push(head->l);
				count2++;
			}
			if (head->r != NULL)
			{
				bfs.push(head->r);
				count2++;
			}
		}
		count1 = count2;
		count2 = 0;
	}
	

	return 0;
}

1063. Set Similarity (25)

1.该题目主要是先输入一些集合,然后查询某两个集合的交集数量除以并集数量。

2.刚开始使用map去存储每个集合,后面再建立一个新的map合并两个集合的map,从而查找交集数量,结果超时。

3.后面改为利用map作集合的重复判断,在输入集合时,通过map的判断,建立一个每个元素都是唯一的vector。

4.合并时,直接申请两个集合数量总和大小的新vector,把两个集合的vector复制进去,然后进行排序,通过检测元素是否出现两次,来实现检测交集。

5.新vector的size减去交集大小,就是并集。

6.通过这种数据结构和方法,成功AC题目。

1063

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

Given two sets of integers, the similarity of the sets is defined to be Nc/Nt*100%, where Nc is the number of distinct common numbers shared by the two sets, and Nt is the total number of distinct numbers in the two sets. Your job is to calculate the similarity of any given pair of sets.

Input Specification:

Each input file contains one test case. Each case first gives a positive integer N (<=50) which is the total number of sets. Then N lines follow, each gives a set with a positive M (<=104) and followed by M integers in the range [0, 109]. After the input of sets, a positive integer K (<=2000) is given, followed by K lines of queries. Each query gives a pair of set numbers (the sets are numbered from 1 to N). All the numbers in a line are separated by a space.

Output Specification:

For each query, print in one line the similarity of the sets, in the percentage form accurate up to 1 decimal place.

Sample Input:

3
3 99 87 101
4 87 101 5 87
7 99 101 18 5 135 18 99
2
1 2
1 3

Sample Output:

50.0%
33.3%

 
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;

int main(void)
{
	int total;
	scanf("%d", &total);
	vector<map<int, int>> m(total);
	vector<vector<int>> ele(total);
	for (int i = 0; i < total; i++)
	{
		int n;
		scanf("%d", &n);
		for (int j = 0; j < n; j++)
		{
			int tmp;
			scanf("%d", &tmp);
			if (m[i][tmp] == 0)
			{
				m[i][tmp] = 1;
				ele[i].push_back(tmp);
			}
		}
	}
	int querySum;
	scanf("%d", &querySum);
	for (int i = 0; i < querySum; i++)
	{
		int a;
		int b;
		scanf("%d %d", &a, &b);
		a--;
		b--;
		vector<int> cal(ele[a].size() + ele[b].size());
		for (int i = 0; i < ele[a].size(); i++)
		{
			cal[i] = ele[a][i];
		}
		for (int i = ele[a].size(); i < ele[a].size() + ele[b].size(); i++)
		{
			cal[i] = ele[b][i - ele[a].size()];
		}
		double same = 0;
		sort(cal.begin(), cal.end());
		for (int i = 0; i < cal.size()-1; i++)
		{
			if (cal[i] == cal[i + 1])
				same++;
		}
		double ans = same / (cal.size() - same) * 100;
		printf("%.1lf%\n", ans);
	}
	return 0;
}

1062. Talent and Virtue (25)

1.给出一些ID及对应的天赋和美德分数,主要涉及到一个根据规则排序的问题。

2.分类规则:

1)圣人,sages,virtue和talent都要>=high

2)君子,nobleman,virtue>=high,talent<high,talent>=low

3)愚人,fool man,low<=talent<=virtue<high

4)愚人之后仍显示的,virtue>=low,talent>=low

3.跟结构体增加了一个level的变量,记录其所在的等级,排序比较函数如下:

bool cmp(const ManNode&a, const ManNode&b)
{
	if (a.level > b.level)
		return true;
	else if (a.level == b.level && a.total > b.total)
		return true;
	else if (a.level == b.level && a.total == b.total&& a.virtue > b.virtue)
		return true;
	else if (a.level == b.level && a.total == b.total&& a.virtue == b.virtue&& a.id < b.id)
		return true;
	else
		return false;
}

1062

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

About 900 years ago, a Chinese philosopher Sima Guang wrote a history book in which he talked about people’s talent and virtue. According to his theory, a man being outstanding in both talent and virtue must be a “sage(圣人)”; being less excellent but with one’s virtue outweighs talent can be called a “nobleman(君子)”; being good in neither is a “fool man(愚人)”; yet a fool man is better than a “small man(小人)” who prefers talent than virtue.

Now given the grades of talent and virtue of a group of people, you are supposed to rank them according to Sima Guang’s theory.

Input Specification:

Each input file contains one test case. Each case first gives 3 positive integers in a line: N (<=105), the total number of people to be ranked; L (>=60), the lower bound of the qualified grades — that is, only the ones whose grades of talent and virtue are both not below this line will be ranked; and H (<100), the higher line of qualification — that is, those with both grades not below this line are considered as the “sages”, and will be ranked in non-increasing order according to their total grades. Those with talent grades below H but virtue grades not are cosidered as the “noblemen”, and are also ranked in non-increasing order according to their total grades, but they are listed after the “sages”. Those with both grades below H, but with virtue not lower than talent are considered as the “fool men”. They are ranked in the same way but after the “noblemen”. The rest of people whose grades both pass the L line are ranked after the “fool men”.

Then N lines follow, each gives the information of a person in the format:

ID_Number Virtue_Grade Talent_Grade

where ID_Number is an 8-digit number, and both grades are integers in [0, 100]. All the numbers are separated by a space.Output Specification:

The first line of output must give M (<=N), the total number of people that are actually ranked. Then M lines follow, each gives the information of a person in the same format as the input, according to the ranking rules. If there is a tie of the total grade, they must be ranked with respect to their virtue grades in non-increasing order. If there is still a tie, then output in increasing order of their ID’s.

Sample Input:

14 60 80
10000001 64 90
10000002 90 60
10000011 85 80
10000003 85 80
10000004 80 85
10000005 82 77
10000006 83 76
10000007 90 78
10000008 75 79
10000009 59 90
10000010 88 45
10000012 80 100
10000013 90 99
10000014 66 60

Sample Output:

12
10000013 90 99
10000012 80 100
10000003 85 80
10000011 85 80
10000004 80 85
10000007 90 78
10000006 83 76
10000005 82 77
10000002 90 60
10000014 66 60
10000008 75 79
10000001 64 90

 
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;

struct ManNode{
	int id;//输出时要注意是8位
	int virtue, talent;
	int level, total;
	ManNode() :id(0), virtue(0), talent(0), level(0), total(0){};

};
bool cmp(const ManNode&a, const ManNode&b)
{
	if (a.level > b.level)
		return true;
	else if (a.level == b.level && a.total > b.total)
		return true;
	else if (a.level == b.level && a.total == b.total&& a.virtue > b.virtue)
		return true;
	else if (a.level == b.level && a.total == b.total&& a.virtue == b.virtue&& a.id < b.id)
		return true;
	else
		return false;
}
int main(void)
{
	int manSum, low, high;
	cin >> manSum >> low >> high;
	vector<ManNode> man(manSum);
	for (int i = 0; i < man.size(); i++)
	{
		scanf("%d %d %d", &man[i].id, &man[i].virtue, &man[i].talent);
		man[i].total = man[i].virtue + man[i].talent;
		if (man[i].virtue >= high&&man[i].talent >= high)
			man[i].level = 4;//圣人,sages
		else if (man[i].virtue >= high&&man[i].talent < high && man[i].talent >= low)
			man[i].level = 3;//君子,nobleman
		else if (man[i].virtue < high && man[i].virtue >= man[i].talent && man[i].talent>=low)
			man[i].level = 2;//愚人,fool man
		else if (man[i].virtue >= low&&man[i].talent >= low)
			man[i].level = 1;//排在愚人之后,其他的不显示

	}
	sort(man.begin(), man.end(), cmp);

	int outPut = 0;
	for (int i = 0; i < man.size(); i++)
	{//统计需要显示的人数
		if (man[i].level>=1)
			outPut++;
		else
			break;
	}
	cout << outPut << endl;
	for (int i = 0; i < outPut; i++)
	{
		printf("%08d %d %d\n", man[i].id, man[i].virtue, man[i].talent);
	}

	return 0;
}

1061. Dating (20)

1.根据给出的规则对string进行匹配解密。

2.第一对string中,DAY的char需要限制在A到G之间,一个星期只有7天;HOUR的char需要限制在A到N,0到9之间,这样才是合理的0~23小时

3.之前卡在了没有限制HOUR的char需要限制在A到N,0到9之间。

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

Sherlock Holmes received a note with some strange strings: “Let’s date! 3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hyscvnm”. It took him only a minute to figure out that those strange strings are actually referring to the coded time “Thursday 14:04” — since the first common capital English letter (case sensitive) shared by the first two strings is the 4th capital letter ‘D’, representing the 4th day in a week; the second common character is the 5th capital letter ‘E’, representing the 14th hour (hence the hours from 0 to 23 in a day are represented by the numbers from 0 to 9 and the capital letters from A to N, respectively); and the English letter shared by the last two strings is ‘s’ at the 4th position, representing the 4th minute. Now given two pairs of strings, you are supposed to help Sherlock decode the dating time.

Input Specification:

Each input file contains one test case. Each case gives 4 non-empty strings of no more than 60 characters without white space in 4 lines.

Output Specification:

For each test case, print the decoded time in one line, in the format “DAY HH:MM”, where “DAY” is a 3-character abbreviation for the days in a week — that is, “MON” for Monday, “TUE” for Tuesday, “WED” for Wednesday, “THU” for Thursday, “FRI” for Friday, “SAT” for Saturday, and “SUN” for Sunday. It is guaranteed that the result is unique for each case.

Sample Input:

3485djDkxh4hhGE 
2984akDfkkkkggEdsb 
s&hgsfdk 
d&Hyscvnm

Sample Output:

THU 14:04

 
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;
 
 
 
int main(void)
{
    string num2Day[] = { "", "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN" };
    string first1, first2, second1, second2;
    //getline(cin, first1);
    //getline(cin, first2);
    //getline(cin, second1);
    //getline(cin, second2);
    cin >> first1>> first2>> second1>> second2;
    char dayChar = -1;
    char hourChar = -1;
    for (int i = 0; i < min(first1.size(), first2.size()); i++)
    {
        if (first1[i] == first2[i] &&( (first1[i] >= 'A'&&first1[i] <= 'N') || (first1[i] >= '0'&&first1[i] <= '9')))
        {//需要限制在A到N,0到9之间,这样才是合适的0~23小时显示,否则会出现测试点不过
            if (dayChar == -1 && (first1[i] >= 'A'&&first1[i] <= 'N'))
                dayChar = first1[i];
            else if (dayChar != -1)
            {
                hourChar = first1[i];
                break;
            }
        }
    }
    int mm;
    for (int i = 0; i < min(second1.size(), second2.size()); i++)
    {
        if (second1[i] == second2[i] && ((second1[i] >= 'A'&&second1[i] <= 'Z') || (second1[i] >= 'a'&&second1[i] <= 'z')))
        {
            mm = i;
            break;
        }
    }
    string day = num2Day[dayChar - 'A' + 1];
    string hour = "";
    int hourInt;
    if (hourChar >= 'A'&&hourChar <= 'Z')
        hourInt = hourChar - 'A' + 10;
    else
        hourInt = hourChar - '0';
    char c = hourInt / 10 + '0';
    hour += c;
    c = hourInt % 10 + '0';
    hour += c;
    cout << day << " " << hour;
    printf(":%02d\n", mm);
 
 
    return 0;
}

1060. Are They Equal (25)

1.题目要求把两个数分别转换成一定精度的数,用科学计数法显示,然后判断两个数是否相等。

2.下面列出了一些测试点,通过这些测试点,也就可以AC了:

3 12300 12358.9
YES 0.123*10^5

1 12300 12358.9
YES 0.1*10^5

1 1.2300 1.23589
YES 0.1*10^1

5 1.2300 1.23589
NO 0.12300*10^1 0.12358*10^1

4 0.01234 0.012345
YES 0.1234*10^-1

5 0.01234 0.012345
NO 0.12340*10^-1 0.12345*10^-1

5 0.1234 0.12345
NO 0.12340*10^0 0.12345*10^0

0 0.11 0
YES 0.*10^0或者YES 0.0*10^0,都可以AC,测试点应该没有这个例子

1 0.1 0
NO 0.1*10^0 0.0*10^0

1 0.0 0.1
NO 0.0*10^0 0.1*10^0

1 0.0 0.000
YES 0.0*10^0

1 00.0 0.000
YES 0.0*10^0

4 00.0 0.000
YES 0.0000*10^0

5 00.0 0.000
YES 0.00000*10^0

1 05.0 5.000
YES 0.5*10^1

1 00.01 0.010
YES 0.1*10^-1

1060

 

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

If a machine can save only 3 significant digits, the float numbers 12300 and 12358.9 are considered equal since they are both saved as 0.123*105 with simple chopping. Now given the number of significant digits on a machine and two float numbers, you are supposed to tell if they are treated equal in that machine.

Input Specification:

Each input file contains one test case which gives three numbers N, A and B, where N (<100) is the number of significant digits, and A and B are the two float numbers to be compared. Each float number is non-negative, no greater than 10100, and that its total digit number is less than 100.

Output Specification:

For each test case, print in a line “YES” if the two numbers are treated equal, and then the number in the standard form “0.d1…dN*10^k” (d1>0 unless the number is 0); or “NO” if they are not treated equal, and then the two numbers in their standard form. All the terms must be separated by a space, with no extra space at the end of a line.

Note: Simple chopping is assumed without rounding.

Sample Input 1:

3 12300 12358.9

Sample Output 1:

YES 0.123*10^5

Sample Input 2:

3 120 128

Sample Output 2:

NO 0.120*10^3 0.128*10^3

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 12300 12358.9
YES 0.123*10^5

1 12300 12358.9
YES 0.1*10^5

1 1.2300 1.23589
YES 0.1*10^1

5 1.2300 1.23589
NO 0.12300*10^1 0.12358*10^1

4 0.01234 0.012345
YES 0.1234*10^-1

5 0.01234 0.012345
NO 0.12340*10^-1 0.12345*10^-1

5 0.1234 0.12345
NO 0.12340*10^0 0.12345*10^0

0 0.11 0
YES 0.*10^0或者YES 0.0*10^0,都可以AC,测试点应该没有这个例子

1 0.1 0
NO 0.1*10^0 0.0*10^0

1 0.0 0.1
NO 0.0*10^0 0.1*10^0

1 0.0 0.000
YES 0.0*10^0

1 00.0 0.000
YES 0.0*10^0

4 00.0 0.000
YES 0.0000*10^0

5 00.0 0.000
YES 0.00000*10^0

1 05.0 5.000
YES 0.5*10^1

1 00.01 0.010
YES 0.1*10^-1
*/
bool isNum(char c)
{
	return (c <= '9'&&c >= '0');
}
string fixN(int n, string s)
{//如果不足N位,则补0,如果超过n位,则截断
	if (n == 0) return "0";
	if (s.size() >= n)
		return s.substr(0, n);
	else
	{
		//return s;//不补0,也可以
		int size = s.size();//在这里卡住了,本来下面的条件是i<n-s.size()+1,这样的话随着s补零,s的长度发生变化
		for (int i = 0; i < n - size; i++)
			s += '0';
		return s;//补0,也可以
	}
}
string num2String(int a)
{
	if (a == 0) return "0";
	string ans = "";
	while (a != 0)
	{
		char c = a % 10 + '0';
		ans += c;
		a /= 10;
	}
	return ans;
}
string trans(int n, string str)
{

	if (str == "0")
	{
		string tmp = "";
		for (int i = 0; i < n - str.size() + 1; i++)
			tmp += '0';
		if (tmp == "") tmp = "0";
		return str + "." + tmp + "*10^0";
	}
	else if (str[0] == '0')
	{//小数:0.1   0.0001
		int p = 0;
		string tmp = "";
		for (int i = 0; i < str.size(); i++)
		{
			if (isNum(str[i]))
				tmp += str[i];
		}

		tmp = tmp.substr(1);//除去整数位的0
		for (int i = 0; i < tmp.size(); i++)
		{//0.00001  有四个连续的0
			if (tmp[i] == '0')
				p++;//计算前面有多少个连续的0
			else break;
		}
		tmp = tmp.substr(p);
		if (tmp == "") p = 0;//如0.0,此时的tmp为0,p为1,截掉后tmp为空,p还有1,p应为0
		tmp = fixN(n, tmp);
		if (p == 0)
			return "0." + tmp + "*10^" + num2String(p);
		else
			return "0." + tmp + "*10^-" + num2String(p);


	}
	else
	{//大于1的数
		int p = -1;//小数点位置
		string tmp = "";
		for (int i = 0; i < str.size(); i++)
		{
			if (isNum(str[i]))
				tmp += str[i];
			if (p == -1 && str[i] == '.')
				p = i;//求得小数点的位置
		}

		if (p == -1)//str多少位,就有多少个10,如1234
			p = str.size();

		tmp = fixN(n, tmp);
		string ans = "0." + tmp + "*10^" + num2String(p);
		return ans;
	}
}
string deleteZero(string a)
{
	int p = 0;
	for (int i = 0; i < a.size() - 1; i++)
	{
		if (a[i] == '0'&&a[i + 1] != '.')
			p++;
		else
			break;
	}
	return a.substr(p);
}
int main(void)
{
	int n;
	string a, b;
	cin >> n >> a >> b;
	//if (n == 0)
	//{//这部分输出YES 0.*10^0或者YES 0.0*10^0,都可以AC,测试点应该没有这个例子
	//	cout << "YES 0.0*10^0" << endl;
	//	return 0;
	//}
	string a2 = trans(n, deleteZero(a));
	b = deleteZero(b);
	string b2 = trans(n, b);
	if (a2 == b2)
		cout << "YES " << a2 << endl;
	else
		cout << "NO " << a2 << " " << b2 << endl;

	return 0;
}

1059. Prime Factors (25)

1.题目要求求一个数的质因数分解。

2.一个大于等于2的数,质因数分解分两种情况:

1)如果这个数是质数,那么质因数分解就是它本身;

2)如果不是质数,那么除去最大的质因数后,剩下的质因数均小于sqrt(n),所以遍历到sqrt(n)即可。

3.注意输入为1的情况,输出应该为1=1。

1059

时间限制
50 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
HE, Qinming

Given any positive integer N, you are supposed to find all of its prime factors, and write them in the format N = p1^k1* p2^k2 *…*pm^km.

Input Specification:

Each input file contains one test case which gives a positive integer N in the range of long int.

Output Specification:

Factor N in the format N = p1^k1 * p2^k2 *…*pm^km, where pi‘s are prime factors of N in increasing order, and the exponent ki is the number of pi — hence when there is only one pi, ki is 1 and must NOT be printed out.

Sample Input:

97532468

Sample Output:

97532468=2^2*11*17*101*1291

 
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;

int main(void)
{
	int n;
	cin >> n;
	int outPur = n;

	vector<pair<int, int>> factor(0);

	int tmp = sqrt(n) + 1;
	for (int i = 2; i <= tmp; i++)
	{//遍历到sqrt(n)+1即可
		if (n%i == 0)
		{
			factor.push_back({ i, 1 });
			n /= i;
			while (n%i == 0)
			{
				factor.back().second++;
				n /= i;
			}
		}
	}
	if (n != 1)//如果最后不为1,那么这个是最大质因数
		factor.push_back({ n, 1 });
	if (outPur == 1)
	{//注意1的情况
		printf("1=1\n");
		return 0;
	}
	printf("%d=", outPur);
	for (int i = 0; i < factor.size(); i++)
	{
		printf("%d", factor[i].first);
		if (factor[i].second != 1)
			printf("^%d", factor[i].second);
		if (i != factor.size() - 1)
			printf("*");
	}
	cout << endl;

	return 0;
}

1058. A+B in Hogwarts (20)

1.给出两个数,根据题目要求进行加法运算。

2.该题不难,主要是字符串的处理和进制处理。

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

If you are a fan of Harry Potter, you would know the world of magic has its own currency system — as Hagrid explained it to Harry, “Seventeen silver Sickles to a Galleon and twenty-nine Knuts to a Sickle, it’s easy enough.” Your job is to write a program to compute A+B where A and B are given in the standard form of “Galleon.Sickle.Knut” (Galleon is an integer in [0, 107], Sickle is an integer in [0, 17), and Knut is an integer in [0, 29)).

Input Specification:

Each input file contains one test case which occupies a line with A and B in the standard form, separated by one space.

Output Specification:

For each test case you should output the sum of A and B in one line, with the same format as the input.

Sample Input:

3.2.1 10.16.27

Sample Output:

14.1.28

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;

bool isNum(char c)
{
	if (c <= '9'&&c >= '0') return true;
	else return false;
}
void string2Num(string a,int&a1, int&a2, int&a3)
{
	int idx = 0;
	for (int i = 0; i < a.size(); i++)
	{
		if (idx == 0 && isNum(a[i]))
			a1 = a1 * 10 + a[i] - '0';
		else if (idx == 1 && isNum(a[i]))
			a2 = a2 * 10 + a[i] - '0';
		else if (idx == 2 && isNum(a[i]))
			a3 = a3 * 10 + a[i] - '0';
		else if (a[i] == '.')
		{
			idx++;
		}
	}
}
int main(void)
{
	
	string a, b;
	cin >> a >> b;
	int a1 = 0, a2 = 0, a3 = 0;
	int b1 = 0, b2 = 0, b3 = 0;

	string2Num(a, a1, a2, a3);
	string2Num(b, b1, b2, b3);

	int carry = 0;
	a3 = a3 + b3;
	carry = a3 / 29;
	a3 %= 29;
	a2 = a2 + b2 + carry;
	carry = a2 / 17;
	a2 %= 17;
	a1 = a1 + b1 + carry;

	printf("%d.%d.%d\n", a1, a2, a3);

	return 0;
}

1057. Stack (30)

1.该题重点!主要是模拟栈操作,能够频繁读取栈中元素的中位数。

2.本题的中间三个测试点非常容易超时。

3.需要采用树状数组+二分法

树状数组:能够在o(logn)的时间内进行对a[i]操作和统计a[0]+a[1]+a[2]+…a[i]的操作。

我们把a[i]记录为i的出现次数,那么统计sum=a[0]+a[1]+a[2]+…a[i],就可以知道小于等于i的元素出现的次数。而PeekMedian操作中,是求n/2或者(n+1)/2的元素,即当sum等于n/2或者(n+1)/2时,i就是我们需要输出的元素

4.利用树状数组,能够快速统计sum,利用二分法,能够快速定位i。

5.后续优化:可以考虑采用一个数组实现stack的功能,int stack[N];   int stackTop=0;//既是栈顶元素在stack数组的位置,也是栈内元素的总个数,push操作:stack[++stackTop]=x,  pop操作:stack[stackTop–].

20151127190935810

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

Stack is one of the most fundamental data structures, which is based on the principle of Last In First Out (LIFO). The basic operations include Push (inserting an element onto the top position) and Pop (deleting the top element). Now you are supposed to implement a stack with an extra operation: PeekMedian — return the median value of all the elements in the stack. With N elements, the median value is defined to be the (N/2)-th smallest element if N is even, or ((N+1)/2)-th if N is odd.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<= 105). Then N lines follow, each contains a command in one of the following 3 formats:

Push key
Pop
PeekMedianwhere key is a positive integer no more than 105.

Output Specification:

For each Push command, insert key into the stack and output nothing. For each Pop or PeekMedian command, print in a line the corresponding returned value. If the command is invalid, print “Invalid” instead.

Sample Input:

17
Pop
PeekMedian
Push 3
PeekMedian
Push 2
PeekMedian
Push 1
PeekMedian
Pop
Pop
Push 5
Push 4
PeekMedian
Pop
Pop
Pop
Pop

Sample Output:

Invalid
Invalid
3
2
2
1
2
4
4
5
3
Invalid

 
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;
#define MAX_N 100001

int Tree[MAX_N];
inline int lowbit(int x)
{
	return(x&-x);
}

void add(int x, int value)
{
	for (int i = x; i < MAX_N; i += lowbit(i))
		Tree[i] += value;
}
int get(int x)
{//获取0到x的数组总和
	int sum = 0;
	for (int i = x; i; i -= lowbit(i))
		sum += Tree[i];
	return sum;
}

int main(void)
{
	int n;
	cin >> n;
	char action[11];
	stack<int> sta;
	int maxNum = INT_MIN;
	int minNum = INT_MAX;
	memset(Tree, 0, sizeof(Tree));
	for (int i = 0; i < n; i++)
	{
		scanf("%s", action);
		if (action[2] == 'p')
		{//pop
			if (sta.empty())
			{
				cout << "Invalid" << endl;
				continue;
			}
			int top = sta.top();
			sta.pop();
			add(top, -1);//弹出,出现次数减1
			printf("%d\n", top);
		}
		else if (action[2] == 'e')
		{//PeekMedian
			if (sta.empty())
			{
				cout << "Invalid" << endl;
				continue;
			}
			int n = sta.size();//栈里的元素个数
			int target = 0;
			if (n % 2 == 0)
				target = n / 2;
			else
				target = (n + 1) / 2;

			//设中位数为i,用二分法查找
			int l = 0;
			int r = MAX_N - 1;
			while (l <r - 1)
			{
				int mid = (l + r) / 2;
				if (get(mid) < target)
					l = mid;
				else//如果get(mid)<=target,则r=mid,逐渐逼近
					r = mid;
			}
			printf("%d\n", l + 1);
		}
		else
		{//push
			int tmp;
			scanf("%d", &tmp);
			sta.push(tmp);
			maxNum = max(maxNum, tmp);
			minNum = min(minNum, tmp);
			add(tmp, 1);//弹出,出现次数加1
		}
	}
	return 0;
}