1092. To Buy or Not to Buy (20)

1.题目要求给出目标串和原串,求种类差异和数目差异。

2.使用哈希表分别记录两串的bead数量

3.需要使用迭代器进行遍历,避免出现重复情况:

如ppRYYGrrYBR2258和YrR8RrY,用YrR8RrY来遍历,则前面遍历了R,后面又遍历了R,导致统计的重复。

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

Eva would like to make a string of beads with her favorite colors so she went to a small shop to buy some beads. There were many colorful strings of beads. However the owner of the shop would only sell the strings in whole pieces. Hence Eva must check whether a string in the shop contains all the beads she needs. She now comes to you for help: if the answer is “Yes”, please tell her the number of extra beads she has to buy; or if the answer is “No”, please tell her the number of beads missing from the string.

For the sake of simplicity, let’s use the characters in the ranges [0-9], [a-z], and [A-Z] to represent the colors. For example, the 3rd string in Figure 1 is the one that Eva would like to make. Then the 1st string is okay since it contains all the necessary beads with 8 extra ones; yet the 2nd one is not since there is no black bead and one less red bead.

1092Figure 1
Input Specification:

Each input file contains one test case. Each case gives in two lines the strings of no more than 1000 beads which belong to the shop owner and Eva, respectively.

Output Specification:

For each test case, print your answer in one line. If the answer is “Yes”, then also output the number of extra beads Eva has to buy; or if the answer is “No”, then also output the number of beads missing from the string. There must be exactly 1 space between the answer and the number.

Sample Input 1:

ppRYYGrrYBR2258
YrR8RrY

Sample Output 1:

Yes 8

Sample Input 2:

ppRYYGrrYB225
YrR8RrY

Sample Output 1:

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


int main(void)
{
	string give, favourite;
	cin >> give >> favourite;
	map<char, int> giveCount;
	map<char, int> fCount;
	for (int i = 0; i < give.size(); i++)
	{
		giveCount[give[i]]++;
	}
	for (int i = 0; i < favourite.size(); i++)
	{
		fCount[favourite[i]]++;
	}
	int more = 0;
	int less = 0;
	bool satify = true;
	for (map<char, int>::iterator ite = fCount.begin(); ite != fCount.end();ite++)
	{//需要使用迭代器进行遍历,避免出现重复情况
		/*
		如ppRYYGrrYBR2258和YrR8RrY,用YrR8RrY来遍历,则前面遍历了R,后面又遍历了R,导致统计的重复
		*/
		int bead = ite->first;
		if (satify && fCount[bead] <= giveCount[bead])
			more += giveCount[bead] - fCount[bead];
		else
		{
			satify = false;
			if (fCount[bead] > giveCount[bead])
				less += fCount[bead] - giveCount[bead];
		}
	}
	if (satify)
	{
		cout << "Yes " << give.size() - favourite.size() << endl;
	}
	else
		cout << "No " << less << endl;
	return 0;
}

1091. Acute Stroke (30)

1.给出多个图像(二维矩阵),求出满足阈值的中风区域。

2.主要是考察并查集。

3.每输入一个像素点,就检测它的上边,左边,上一层的位置是否为1,为1的话,归为一个集合。

4.最后对集合的数量进行统计。

1091

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

One important factor to identify acute stroke (急性脑卒中) is the volume of the stroke core. Given the results of image analysis in which the core regions are identified in each MRI slice, your job is to calculate the volume of the stroke core.

Input Specification:

Each input file contains one test case. For each case, the first line contains 4 positive integers: M, N, L and T, where M and N are the sizes of each slice (i.e. pixels of a slice are in an M by N matrix, and the maximum resolution is 1286 by 128); L (<=60) is the number of slices of a brain; and T is the integer threshold (i.e. if the volume of a connected core is less than T, then that core must not be counted).

Then L slices are given. Each slice is represented by an M by N matrix of 0’s and 1’s, where 1 represents a pixel of stroke, and 0 means normal. Since the thickness of a slice is a constant, we only have to count the number of 1’s to obtain the volume. However, there might be several separated core regions in a brain, and only those with their volumes no less than T are counted. Two pixels are “connected” and hence belong to the same region if they share a common side, as shown by Figure 1 where all the 6 red pixels are connected to the blue one.

1091-2Figure 1
Output Specification:

For each case, output in a line the total volume of the stroke core.

Sample Input:

3 4 5 2
1 1 1 1
1 1 1 1
1 1 1 1
0 0 1 1
0 0 1 1
0 0 1 1
1 0 1 1
0 1 0 0
0 0 0 0
1 0 1 1
0 0 0 0
0 0 0 0
0 0 0 1
0 0 0 1
1 0 0 0

Sample Output:

26

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;
int find(int*r, int x)
{
	for (; x != r[x]; x = r[x])
		r[x] = r[r[x]];
	return r[x];
}
int find(vector<int>&r, int x)
{
	for (; x != r[x]; x = r[x])
		r[x] = r[r[x]];
	return r[x];
}
int main(void)
{
	int m,n,l,t;//1286,128,60

	cin >> m >> n >> l >> t;
	char *image = new char[m*n*l];
	memset(image, 0, sizeof(image));
	//int *r = new int[m*n*l];
	//memset(r, -1, sizeof(r));
	vector<int> r(m*n*l, -1);
	for (int k = 0; k < l; k++)
	{
		for (int j = 0; j < m; j++)
		{
			for (int i = 0; i < n; i++)
			{
				int tmp = k*(m*n) + j*n + i;
				scanf("%d", &image[k*(m*n) + j*n + i]);
				if (image[k*(m*n) + j*n + i] == 1)
				{
					if (r[k*(m*n) + j*n + i] == -1)//如果为-1,则还没初始化代表,进行初始化代表为自己
						r[k*(m*n) + j*n + i] = k*(m*n) + j*n + i;
					if (i>0 && image[k*(m*n) + j*n + (i - 1)] == 1)
					{//上面
						r[find(r, k*(m*n) + j*n + i)] = find(r, k*(m*n) + j*n + (i - 1));
					}
					if (j>0 && image[k*(m*n) + (j-1)*n + i] == 1)
					{//左边
						r[find(r, k*(m*n) + j*n + i)] = find(r, k*(m*n) + (j - 1)*n + i);
					}
					if (k>0 && image[(k-1)*(m*n) + j*n + i] == 1)
					{//上一层
						r[find(r, k*(m*n) + j*n + i)] = find(r, (k - 1)*(m*n) + j*n + i);
					}
				}
			}
		}
	}
	map<int, int> hash;
	int sum = 0;
	for (int k = 0; k < l; k++)
	{
		for (int j = 0; j < m; j++)
		{
			for (int i = 0; i < n; i++)
			{
				if (image[k*(m*n) + j*n + i] == 1)
				{
					int tmp = find(r, k*(m*n) + j*n + i);
					hash[tmp]++;
					if (hash[tmp] == t)
						sum += t;
					else if (hash[tmp] > t)
						sum++;
				}
			}
		}
	}
	cout << sum << endl;
	
	
	return 0;
}

1102 Individual Income Tax

1.该题给出税收,反过来求月薪,难度不大;
2.计算公式为(税收-分级税收)/当级税收比率+前一级的薪资。

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

For incomes from wages and salaries, the progressive tax rate in excess of specific amount is applicable. The income amount taxable shall be the remainder after deducting 3500 yuan from the monthly income. The tax rate is below:

Grade Monthly Taxable Income Tax Rate(%)
Income of 1,500 yuan or less 3%
That part of income in excess of 1,500 to 4,500 yuan 10%
That part of income in excess of 4,500 to 9,000 yuan 20%
That part of income in excess of 9,000 to 35,000 yuan 25%
That part of income in excess of 35,000 to 55,000 yuan 30%
That part of income in excess of 55,000 to 80,000 yuan 35%
That part of income in excess of 80,000 yuan 45%

Given the tax Little Hi paid, do you know his salary this month?

输入

Line 1: M, the tax Little Hi paid. (1 <= M <= 5,000,000)

输出

Line 1: Little Hi’s salary. The number should be rounded dowm to the nearest integer.

提示

Little Hi’s salary is 15692 yuan. The tax is calculated below:
The income amount taxable is 15692 – 3500 = 12192 yuan.
That part of income of 1500 or less: 1500 * 3% = 45 yuan.
That part of income in excess of 1,500 to 4,500 yuan: 3000 * 10% = 300 yuan.
That part of income in excess of 4,500 to 9,000 yuan: 4500 * 20% = 900 yuan.
That part of income in excess of 9,000 to 35,000 yuan: (12192 – 9000) * 25% = 798 yuan.
Total tax is 45 + 300 + 900 + 798 = 2043 yuan.

样例输入
2043
样例输出
15692

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 tax;
	cin >> tax;
	//建立一个税收范围数组
	vector<int> taxRange = { 0,45, 300, 900, 6500, 6000, 8750 };
	//建立一个税收比率数组
	vector<double> rate = { 0.03, 0.1, 0.2, 0.25, 0.3, 0.35,0.45 };
	//建立一个薪资数组
	vector<int> salaryRange = { 0,1500, 4500, 9000, 35000, 55000, 80000 };
	int level = 0;
	int sum = 0;
	for (; level < taxRange.size(); level++)
	{//求出刚好超过用户税收的等级
		sum += taxRange[level];
		if (tax < sum)
			break;
	}
	sum -= taxRange[level--];//求得用户刚好所在的收税等级,和在该等级多出的钱
	//计算工资
	int salary = (tax - sum) / rate[level] + salaryRange[level];
	//注意需要加上3500元
	cout << salary+3500 << endl;
	return 0;

}


1014 Trie树

1.建立Trie树,因为文中提及输入的单词字母不一定是英文字母,有可能是火星文(><?:{}”等等),所以采用map来存储儿子节点,数据结构如下:

struct TrieNode{
	map<char, TrieNode*> child;//使用map来存储,便于查找,题目提到不一定是英文字母
	int count;
	TrieNode(int x) :count(x){};
	TrieNode() :count(0){};
};

2.查询和插入并没有太大的难度,具体参考后面的代码。

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进。

这一天,他们遇到了一本词典,于是小Hi就向小Ho提出了那个经典的问题:“小Ho,你能不能对于每一个我给出的字符串,都在这个词典里面找到以这个字符串开头的所有单词呢?

身经百战的小Ho答道:“怎么会不能呢!你每给我一个字符串,我就依次遍历词典里的所有单词,检查你给我的字符串是不是这个单词的前缀不就是了?

小Hi笑道:“你啊,还是太年轻了!~假设这本词典里有10万个单词,我询问你一万次,你得要算到哪年哪月去?”

小Ho低头算了一算,看着那一堆堆的0,顿时感觉自己这辈子都要花在上面了…

小Hi看着小Ho的囧样,也是继续笑道:“让我来提高一下你的知识水平吧~你知道树这样一种数据结构么?”

小Ho想了想,说道:“知道~它是一种基础的数据结构,就像这里说的一样!”

小Hi满意的点了点头,说道:“那你知道我怎么样用一棵树来表示整个词典么?”

小Ho摇摇头表示自己不清楚。

提示一:Trie树的建立

“你看,我们现在得到了这样一棵树,那么你看,如果我给你一个字符串ap,你要怎么找到所有以ap开头的单词呢?”小Hi又开始考校小Ho。

“唔…一个个遍历所有的单词?”小Ho还是不忘自己最开始提出来的算法。

“笨!这棵树难道就白构建了!”小Hi教训完小Ho,继续道:“看好了!”

提示二:如何使用Trie树

提示三:在建立Trie树时同时进行统计!

“那么现在!赶紧去用代码实现吧!”小Hi如是说道

输入

输入的第一行为一个正整数n,表示词典的大小,其后n行,每一行一个单词(不保证是英文单词,也有可能是火星文单词哦),单词由不超过10个的小写英文字母组成,可能存在相同的单词,此时应将其视作不同的单词。接下来的一行为一个正整数m,表示小Hi询问的次数,其后m行,每一行一个字符串,该字符串由不超过10个的小写英文字母组成,表示小Hi的一个询问。

在20%的数据中n, m<=10,词典的字母表大小<=2.

在60%的数据中n, m<=1000,词典的字母表大小<=5.

在100%的数据中n, m<=100000,词典的字母表大小<=26.

本题按通过的数据量排名哦~

输出

对于小Hi的每一个询问,输出一个整数Ans,表示词典中以小Hi给出的字符串为前缀的单词的个数。

样例输入
5
babaab
babbbaaaa
abba
aaaaabaa
babaababb
5
babb
baabaaa
bab
bb
bbabbaab
样例输出
1
0
3
0
0

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
babaab
babbbaaaa
abba
aaaaabaa
babaababb
5
babb
baabaaa
bab
bb
bbabbaab

5
babaab
babaab
babaab
babaab
babaab
5
babaab
babaab
babaab
babaab
babaab

*/
struct TrieNode{
	map<char, TrieNode*> child;//使用map来存储,便于查找,题目提到不一定是英文字母
	int count;
	TrieNode(int x) :count(x){};
	TrieNode() :count(0){};
};

//单词插入函数
void insertWord(char *a, int pos, TrieNode*p)
{
	if (a[pos] == 0) return;//已经遍历完毕
	else
	{
		if (p->child.find(a[pos])!= p->child.end())
		{//找到有这个字母
			p->child[a[pos]]->count++;//插入的同时进行统计
			insertWord(a, pos + 1, p->child[a[pos]]);//递归插入
		}
		else
		{//没找到,则新插入一个
			p->child[a[pos]] = new TrieNode(1);//默认count为1
			insertWord(a, pos + 1, p->child[a[pos]]);//递归插入
		}
	}
}
int searchWord(char *a, int pos, TrieNode *p)
{

	if (p->child[a[pos]] != NULL)
	{//找到有这个字母
		if (a[pos+1]==0)//如果下个char为0,即当前char为单词的最后一个字母,则值金额返回
			return	p->child[a[pos]]->count;
		else //否则,递归查找
			return searchWord(a, pos + 1, p->child[a[pos]]);
	}
	else
	{//没找到,则新插入一个
		return 0;
	}
}
int main()
{
	TrieNode* root = new TrieNode(0);//建立一个根节点,不存储任何值,只用来连接第一个单词的字母,如单词acb和efg,a和e是root的儿子
	int n;//输入单词的个数
	scanf("%d", &n);
	char word[11];
	for (int i = 0; i < n; i++)
	{
		scanf("%s", word);
		insertWord(word, 0, root);
	}
	int querySum;//查询的次数
	scanf("%d", &querySum);
	for (int i = 0; i < querySum; i++)
	{
		scanf("%s", word);
		if (word[0] == 0) printf("0\n");//如果输入单词为空,直接输出0
		else printf("%d\n", searchWord(word, 0, root));
	}
	return 0;
}


310 Minimum Height Trees(Medium)

1.这道题目主要是求一个无向图中,以哪个节点为根节点的树的高度最小;

2.常规方法可以使用BFS或者DFS,对每个点都遍历一遍,求出所有点组成的树的高度,然后找出哪些高度最小的节点,可以通过不断更新最低高度来进行剪枝。实际上我写了BFS和DFS的程序,均出现超时。

3.最终的解题思路采用了不断删除叶子节点,逐渐逼近根节点的方法,在删除叶子节点的同时,会有一些新的节点成为叶子节点,于是继续循环删除,直至不能删除为止,那么剩下的节点就是高度最小的根。

4.当n等于1时,需要特殊处理,直接返回{0}。

5.最终会剩下1个节点或者2个节点,1个节点的情况比较好理解,如{0,1}{0,2},同时删除了叶子节点1和2,就剩下0;而两个节点的情况为{0,1},此时0和1的邻居均为1,都是叶子节点,在下一轮操作后,0和1均没有邻居,所以这两个节点都是正确的答案。

6.采用下面的数据结构进行存储,其中采用set是因为便于删除邻居。

struct TreeNode{
	set<int> list;//使用set结构方便删除邻居
	TreeNode(){};
	bool isLeaf(){ return list.size() == 1; };//如果是叶子节点,那么邻居大小是1
};

7.生成用节点存储的树时,耗费的空间为O(V+2E),即V个节点和2E条边;时间复杂度为O(E),即逐渐删除边,直到边的数量为0。(生成树的时候也是遍历了E次)

For a undirected graph with tree characteristics, we can choose any node as the root. The result graph is then a rooted tree. Among all possible rooted trees, those with minimum height are called minimum height trees (MHTs). Given such a graph, write a function to find all the MHTs and return a list of their root labels.

Format
The graph contains n nodes which are labeled from 0 to n - 1. You will be given the number n and a list of undirected edges (each edge is a pair of labels).

You can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0, 1] is the same as [1, 0] and thus will not appear together in edges.

Example 1:

Given n = 4, edges = [[1, 0], [1, 2], [1, 3]]

        0
        |
        1
       / \
      2   3

return [1]

Example 2:

Given n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]

     0  1  2
      \ | /
        3
        |
        4
        |
        5

return [3, 4]

Hint:

  1. How many MHTs can a graph have at most?

Note:

(1) According to the definition of tree on Wikipedia: “a tree is an undirected graph in which any two vertices are connected by exactly one path. In other words, any connected graph without simple cycles is a tree.”

(2) The height of a rooted tree is the number of edges on the longest downward path between the root and a leaf.

Credits:
Special thanks to @peisi for adding this problem and creating all test cases.

Update (2015-11-25):
The function signature had been updated to return List<Integer> instead of integer[]. Please click the reload button above the code editor to reload the newest default code definition.

Subscribe to see which companies asked this question

AC代码:


class Solution {
public:
	struct TreeNode{
		set<int> list;//使用set结构方便删除邻居
		TreeNode(){};
		bool isLeaf(){ return list.size() == 1; };//如果是叶子节点,那么邻居大小是1
	};
	vector<int> findMinHeightTrees(int n, vector<pair<int, int>>& edges) {

		if (n == 1) return{ 0 };//当n为1时,初始化node1为空,下面的程序执行结果会输出空

		vector<TreeNode> tree(n);
		for (auto e : edges)
		{//使用节点来存储这棵树,耗费的空间为O(n+2e)
			tree[e.first].list.insert(e.second);
			tree[e.second].list.insert(e.first);
		}

		vector<int> node1(0);//记录当前的叶子节点
		vector<int> node2(0);//记录删除node1叶子节点后,成为新的叶子节点的节点

		for (int i = 0; i < tree.size();i++)
		{//记录叶子节点
			if (tree[i].isLeaf())
				node1.push_back(i);
		}
		
		while (1)
		{
			for (auto leaf:node1)
			{
				//使用迭代器遍历邻居
				for (set<int>::iterator ite = tree[leaf].list.begin(); ite != tree[leaf].list.end(); ite++)
				{
					int neighbor = *ite;
					tree[neighbor].list.erase(leaf);//删除叶子节点
					if (tree[neighbor].isLeaf())//删除后,如果是叶子节点,则放到node2中
						node2.push_back(neighbor);
				}
			}
			if (node2.empty())
			{//遍历完后,如果node2为空,即node1中的节点不是叶子节点,要么是剩下一个节点,要么剩下两个相互连接的节点
				break;
			}
			node1.clear();
			swap(node1, node2);
		}
		if (node1.size() != 0)
			return node1;//node1中只剩下1个节点,因为邻居为空,所以不能压进node2中
		else if (node1.size() == 0)
			return node2;//node1中有两个节点,且互相连接,邻居都为1,所以被压进node2中(此时邻居都被清除),然后在下一轮循环,两者都不被视为叶子节点
	}
};

关于scanf,printf,char与strcm

在做1028. List Sorting (25)题目的时候需要使用到scanf,printf,char[]和strcmp,下面作一些记录。

1. char[] a;


scanf("%s",a);//因为a已经是地址,所以不需要取址符&

2.需要输出000001之类的6位数字,前面为0填充,可以使用如下语法


int num=1;

printf("%06d",num);//输出为000001

3.strcmp(a,b)的用法
char[] a;
char[] b;

如果strcmp(a,b)<0,则表示a<b

如果strcmp(a,b)==0,则表示a==b

如果strcmp(a,b)>0,则表示a>b

#1174 : 拓扑排序·一

题目:
1.经典的拓扑排序题目,比较简单。

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

由于今天上课的老师讲的特别无聊,小Hi和小Ho偷偷地聊了起来。

小Ho:小Hi,你这学期有选什么课么?

小Hi:挺多的,比如XXX1,XXX2还有XXX3。本来想选YYY2的,但是好像没有先选过YYY1,不能选YYY2。

小Ho:先修课程真是个麻烦的东西呢。

小Hi:没错呢。好多课程都有先修课程,每次选课之前都得先查查有没有先修。教务公布的先修课程记录都是好多年前的,不但有重复的信息,好像很多都不正确了。

小Ho:课程太多了,教务也没法整理吧。他们也没法一个一个确认有没有写错。

小Hi:这不正是轮到小Ho你出马的时候了么!

小Ho:哎??

我们都知道大学的课程是可以自己选择的,每一个学期可以自由选择打算学习的课程。唯一限制我们选课是一些课程之间的顺序关系:有的难度很大的课程可能会有一些前置课程的要求。比如课程A是课程B的前置课程,则要求先学习完A课程,才可以选择B课程。大学的教务收集了所有课程的顺序关系,但由于系统故障,可能有一些信息出现了错误。现在小Ho把信息都告诉你,请你帮小Ho判断一下这些信息是否有误。错误的信息主要是指出现了”课程A是课程B的前置课程,同时课程B也是课程A的前置课程”这样的情况。当然”课程A是课程B的前置课程,课程B是课程C的前置课程,课程C是课程A的前置课程”这类也是错误的。

提示:拓扑排序

输入

第1行:1个整数T,表示数据的组数T(1 <= T <= 5)
接下来T组数据按照以下格式:
第1行:2个整数,N,M。N表示课程总数量,课程编号为1..N。M表示顺序关系的数量。1 <= N <= 100,000. 1 <= M <= 500,000
第2..M+1行:每行2个整数,A,B。表示课程A是课程B的前置课程。

输出

第1..T行:每行1个字符串,若该组信息无误,输出”Correct”,若该组信息有误,输出”Wrong”。

样例输入
2
2 2
1 2
2 1
3 2
1 2
1 3
样例输出
Wrong
Correct

AC代码:

/*
题目:
1.进行拓扑排序,比较简单。
*/
/*
*/

#include<string>
#include <iomanip>
#include<fstream>
#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>
//#include<stack>
#include<vector>
#include <algorithm>
using namespace std;

struct CourseNode{
	bool visited;
	int degree;//入度
	vector<int> next;
	CourseNode() :visited(false),degree(0), next(0){};
};

/*
函数名  :main
函数功能:主函数
*/
int main(void)
{

	int t;
	cin >> t;
	while (t--)
	{
		int n, m;
		cin >> n >> m;
		//n门课程
		vector<CourseNode> course(n+1);

		for (int i = 0; i < m; i++)
		{
			int a, b;
			scanf("%d %d", &a, &b);
			course[a].next.push_back(b);
			course[b].degree++;
		}
		bool allOK = false;
		while (1)
		{
			bool change = false;
			allOK = true;
			for (int i = 1; i < course.size(); i++)
			{
				//搜索没有入度的节点
				if (!course[i].visited && course[i].degree == 0)
				{
					change = true;
					//把它的后置课程入度-1
					course[i].visited = true;
					for (int j = 0; j < course[i].next.size(); j++)
					{
						course[course[i].next[j]].degree--;
					}
				}
				else if (course[i].degree!=0)
					allOK = false;

			}
			//如果遍历一遍后没有改变,则退出循环
			if (!change) break;
		}
		if (allOK) printf("Correct\n");
		else printf("Wrong\n");
	}

	return  0;
}

#1186 : Coordinates

题目:
1.p和q都不大,直接遍历求出所有的因数。
2.原计划遍历到p/2或者q/2的,但是发现当p==1或者q==1时,会直接跳出没有遍历,于是直接改为遍历到p或q。

测试用例:1 1

输出应该为:1 1

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

Give you two integers P and Q. Let all divisors of P be X-coordinates. Let all divisors of Q be Y-coordinates.

For example, when P=6 and Q=2, we can get the coordinates (1,1) (1,2) (2,1) (2,2) (3,1) (3,2) (6,1) (6,2).

You should print all possible coordinates in the order which is first sorted by X-coordinate when coincides, sorted by Y-coordinate.

输入

One line with two integers P and Q(1 <= P, Q <= 10000).

输出

The output may contains several lines , each line with two integers Xi and Yi, denoting the coordinates.

样例输入
6 2
样例输出
1 1
1 2
2 1
2 2
3 1
3 2
6 1
6 2

AC代码:

/*
题目:
1.p和q都不大,直接遍历求出所有的因数。
2.原计划遍历到p/2或者q/2的,但是发现当p==1或者q==1时,会直接跳出没有遍历,于是直接改为遍历到p或q。

*/
/*

测试用例:

1 1
正确答案:
1 1

*/

#include<string>
#include <iomanip>
#include<fstream>
#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>
//#include<stack>
#include<vector>
#include <algorithm>
using namespace std;

/*
函数名  :main
函数功能:主函数
*/
int main(void)
{

	int p, q;
	cin >> p>>q;
	set<int> pDivisors;
	set<int> qDivisors;
	//求出所有的因数
	for (int i = 1; i <= max(p, q); i++)
	{
		if (p%i == 0)
		{
			pDivisors.insert(i);
			pDivisors.insert(p / i);
		}
		if (q%i == 0)
		{
			qDivisors.insert(i);
			qDivisors.insert(q / i);
		}
	}

	//进行输出
	vector<int> qDiv(qDivisors.size(), 0); 
	int i = 0;
	for (set<int>::iterator ite = qDivisors.begin(); ite != qDivisors.end(); ite++,i++)
	{
		qDiv[i] = *ite;
	}

	for (set<int>::iterator ite = pDivisors.begin(); ite != pDivisors.end(); ite++)
	{
		for (int j = 0; j < qDiv.size(); j++)
		{
			printf("%d %d\n", *ite, qDiv[j]);
		}
	}

	return  0;
}

300 Longest Increasing Subsequence (Medium)

第一次做题思路201511092250
1.采用map存储,key为nums[i],value为以nums[i]为结尾的最大递增子序列的长度
2.采用map里面的lower_bounder函数直接找出第一个大于或等于nums[i]的位置,位置ite–,然后遍历前面的数,找出比nums[i]的数里面,长度len最长的,令nums[i]的最大递增子序列的长度为len+1
3.AC时间为148ms

Given an unsorted array of integers, find the length of longest increasing subsequence.

For example,
Given [10, 9, 2, 5, 3, 7, 101, 18],
The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. Note that there may be more than one LIS combination, it is only necessary for you to return the length.

Your algorithm should run in O(n2) complexity.

Follow up: Could you improve it to O(n log n) time complexity?

Credits:
Special thanks to @pbrother for adding this problem and creating all test cases.

Subscribe to see which companies asked this question

class Solution {
public:
	int lengthOfLIS(vector<int>& nums) {
		map<int, int> m;
		int maxLength = 0;
		for (int i = 0; i < nums.size(); i++)
		{
			map<int, int>::iterator ite = m.lower_bound(nums[i]);
			if (ite == m.begin())
				m[nums[i]] = 1;
			else
			{
				ite--;
				int tmpMax = ite->second + 1;
				for (; ite != m.begin(); ite--)//寻找比nums[i]小的数,并在这些数里面,找出长度最大的
					tmpMax = max(tmpMax, ite->second + 1);
				if (ite == m.begin())//寻找比nums[i]小的数,并在这些数里面,找出长度最大的
					tmpMax = max(tmpMax, ite->second + 1);
				m[nums[i]] = tmpMax;
			}
			maxLength = max(maxLength, m[nums[i]]);
		}
		return maxLength;
	}
};

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