1056. Mice and Rice (25)

1.题目的要求是,每次选取NG个用户组成一组进行比赛,第一名进入下一轮,其他落败的用户排名相同。

2.刚开始卡在了这里,误以为在最后议论的比赛中,用户要排1,2,3,4。。结果不是,最后一轮,胜出的排第一名,落败的均为第二名。

3.排名的统计,假如这次有N个group,那么这次落败的用户排名为N+1。

4.第三个数组是用户次序,如6 0 8 7 10 5 9 1 4 2 3

则分组为:

6 0 8

7 10 5

9 1 4

2 3

共四个组

1056

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

Mice and Rice is the name of a programming contest in which each programmer must write a piece of code to control the movements of a mouse in a given map. The goal of each mouse is to eat as much rice as possible in order to become a FatMouse.

First the playing order is randomly decided for NP programmers. Then every NG programmers are grouped in a match. The fattest mouse in a group wins and enters the next turn. All the losers in this turn are ranked the same. Every NGwinners are then grouped in the next match until a final winner is determined.

For the sake of simplicity, assume that the weight of each mouse is fixed once the programmer submits his/her code. Given the weights of all the mice and the initial playing order, you are supposed to output the ranks for the programmers.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 positive integers: NP and NG (<= 1000), the number of programmers and the maximum number of mice in a group, respectively. If there are less than NG mice at the end of the player’s list, then all the mice left will be put into the last group. The second line contains NP distinct non-negative numbers Wi (i=0,…NP-1) where each Wiis the weight of the i-th mouse respectively. The third line gives the initial playing order which is a permutation of 0,…NP-1 (assume that the programmers are numbered from 0 to NP-1). All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the final ranks in a line. The i-th number is the rank of the i-th programmer, and all the numbers must be separated by a space, with no extra space at the end of the line.

Sample Input:

11 3
25 18 0 46 37 3 19 22 57 56 10
6 0 8 7 10 5 9 1 4 2 3

Sample Output:

5 5 5 2 5 5 5 3 1 3 5

 
AC代码:
[c language=”++”]
//#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;
vector<int> weight;
bool cmp(const int&a, const int&b)
{
return weight[a] > weight[b];
}
/*
11 3
25 18 0 46 37 3 19 22 57 56 10
6 0 8 7 10 5 9 1 4 2 3

11 3
25 18 0 46 37 3 19 22 57 56 10
0 1 2 3 4 5 6 7 8 9 10

11 11
25 18 0 46 37 3 19 22 57 56 10
0 1 2 3 4 5 6 7 8 9 10

11 10
25 18 0 46 37 3 19 22 57 56 10
0 1 2 3 4 5 6 7 8 9 10

11 10
0 1 2 3 4 5 6 7 8 9 10
0 1 2 3 4 5 6 7 8 9 10
10 5
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
10 4
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
10 3
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
10 2
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
10 1
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
*/
int main(void)
{

int NP, NG;
cin >> NP >> NG;
weight = vector<int>(NP, 0);
vector<int> order(NP, 0);
vector<int> rank(NP, 0);
for (int i = 0; i < NP; i++)
{
scanf("%d", &weight[i]);//输入老鼠重量
}
for (int i = 0; i < NP; i++)
{
scanf("%d", &order[i]);//输入选手的次数,order[i]号选手在i的位置
}

int thisCount = NP ;
while (1)
{
int group;
if (thisCount%NG == 0)
group = thisCount / NG;
else
group = thisCount / NG + 1;
//如果只有0组,或者刚好1组,则全部排名即可
if (group <= 1)
{
sort(order.begin(), order.begin() + thisCount, cmp);
rank[order[0]] = 1;//最后一轮,胜利者为第一名
for (int i = 1; i < thisCount; i++)
{//其他落败的名次相同,均为第2名
rank[order[i]] = 2;
}
break;
}
else
{
int nextCount=0;
for (int i = 0; i < group; i++)
{
int maxNum = order[i*NG];
int maxWeight = weight[maxNum];
for (int j = i*NG + 1; j < min((i + 1)*NG, thisCount); j++)
{
if (maxWeight < weight[order[j]])
{//max落败
rank[maxNum] = group + 1;
maxWeight = weight[order[j]];
maxNum = order[j];
}
else
{//j落败
rank[order[j]] = group + 1;
}
}
//为了节省空间,把排名放在order的0~group-1的位置,不会干扰
order[nextCount++]=maxNum;
}
thisCount = group;
}
}

for (int i = 0; i < rank.size(); i++)
{
printf("%d", rank[i]);
if (i != rank.size()-1)
printf(" ");
}
cout << endl;
return 0;
}

[/c]

1055. The World’s Richest (25)

1.该题重点!题目给出一定的用户,包括用户年龄和净资产,要求后面按照年龄查询用户,按照一定的规则排序。

2.先把用户按照年龄大小排序,因为后面给出的是年龄范围,所以需要快速找出符合年龄要求的用户

3.建立一个年龄数组,该数组记录了以年龄x为左界时,用户数组的idx,以年龄x为右界时,用户数组的idx,通过年龄数组,就可以快速定位到用户数组的对应位置

4.刚开始,在查询输入时,直接定位到用户数组,把对应的用户数组段复制出来,进行排序,但是会超时(卡了还挺久的),然后仔细思考,发现用户数组的数量可能很大,<=100000,查询数量最大为2000,假如每次都复制100000,然后再进行排序,会严重浪费时间。

5.再观察题目,发现最终需要显示的数量最多只有100个,于是考虑建立一个小根堆,把它的大小维持在需要显示的数量showSum,最后复制输出即可。

为什么建立小根堆?我们的目的是要找出财富值最大的showSum个用户,建立小根堆,堆顶为showSum个用户中财富最小的,假如遍历用户j,发现用户j的财富值比小根堆的堆顶要大,那么把用户压入小根堆,再从小根堆中弹出堆顶即可。

1055

 

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

Forbes magazine publishes every year its list of billionaires based on the annual ranking of the world’s wealthiest people. Now you are supposed to simulate this job, but concentrate only on the people in a certain range of ages. That is, given the net worths of N people, you must find the M richest people in a given range of their ages.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 positive integers: N (<=105) – the total number of people, and K (<=103) – the number of queries. Then N lines follow, each contains the name (string of no more than 8 characters without space), age (integer in (0, 200]), and the net worth (integer in [-106, 106]) of a person. Finally there are K lines of queries, each contains three positive integers: M (<= 100) – the maximum number of outputs, and [Amin, Amax] which are the range of ages. All the numbers in a line are separated by a space.

Output Specification:

For each query, first print in a line “Case #X:” where X is the query number starting from 1. Then output the M richest people with their ages in the range [Amin, Amax]. Each person’s information occupies a line, in the format

Name Age Net_Worth

The outputs must be in non-increasing order of the net worths. In case there are equal worths, it must be in non-decreasing order of the ages. If both worths and ages are the same, then the output must be in non-decreasing alphabetical order of the names. It is guaranteed that there is no two persons share all the same of the three pieces of information. In case no one is found, output “None”.Sample Input:

12 4
Zoe_Bill 35 2333
Bob_Volk 24 5888
Anny_Cin 95 999999
Williams 30 -22
Cindy 76 76000
Alice 18 88888
Joe_Mike 32 3222
Michael 5 300000
Rosemary 40 5888
Dobby 24 5888
Billy 24 5888
Nobody 5 0
4 15 45
4 30 35
4 5 95
1 45 50

Sample Output:

Case #1:
Alice 18 88888
Billy 24 5888
Bob_Volk 24 5888
Dobby 24 5888
Case #2:
Joe_Mike 32 3222
Zoe_Bill 35 2333
Williams 30 -22
Case #3:
Anny_Cin 95 999999
Michael 5 300000
Alice 18 88888
Cindy 76 76000
Case #4:
None

AC代码:

[c language=”++”]

//#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 PeopleNode{
int age, netWorth;
char name[9];
PeopleNode() :age(-1), netWorth(-1){};
};

bool cmp(const PeopleNode&a, const PeopleNode&b)
{//根据年龄排序
if (a.age < b.age)
return true;
else
return false;
}
struct cmpHeap{//根据题目的显示规则排序
bool operator()(const PeopleNode&a, const PeopleNode&b)
{
if (a.netWorth > b.netWorth)
return true;
else if (a.netWorth == b.netWorth && a.age < b.age)
return true;
else if (a.netWorth == b.netWorth && a.age == b.age)
{
int asize = 0, bsize = 0;
for (int i = 0; i < 9; i++)
{
if (a.name[i] != 0)
asize++;
else
break;
}
for (int i = 0; i < 9; i++)
{
if (b.name[i] != 0)
bsize++;
else
break;
}
for (int i = 0; i < min(asize, bsize); i++)
{
if (a.name[i] < b.name[i])
return true;
else if (a.name[i] > b.name[i])
return false;
}
if (asize < bsize) return true;
else return false;
}
else
return false;
}
};

int main(void)
{
int peopleSum, querySum;
scanf("%d %d", &peopleSum, &querySum);
vector<PeopleNode> people(peopleSum);
vector<vector<PeopleNode>> agePeople(201);
for (int i = 0; i < peopleSum; i++)
{
scanf("%s %d %d", people[i].name, &people[i].age, &people[i].netWorth);
}

sort(people.begin(), people.end(), cmp);
vector<pair<int, int>> ageRange(201, { -1, -1 });
int idx = 0;

//计算年龄范围数组
for (int i = 0; i < ageRange.size(); i++)
{
if (idx < people.size())//确保idx在size内
{
if (idx == 0 && people[idx].age > i)
{//idx不进行++,而i++,直到i和age相等
ageRange[i].first = 0;
ageRange[i].second = -1;//以-1作为右边界,意思是不存在年龄小于等于i的人
}
else if (idx != 0 && people[idx].age > i)
{//idx不进行++,而i++,直到i和age相等
ageRange[i].first = idx;//i岁的搜索的起始idx,以idx作为左边界
ageRange[i].second = idx – 1;//i岁的搜索的终止idx,以idx-1作为右边界
}
else if (people[idx].age == i)
{//如果i等于年龄
ageRange[i].first = idx;
while (idx < people.size() && people[idx].age == i)
{//一直到age和i不相等
idx++;
}
ageRange[i].second = idx – 1;//第idx个人的年龄不等于i,第idx-1个人的年龄等于i
}
}
else if (i>0)
{//如果i的值大于0,且idx超出范围(即已经遍历完用户)
ageRange[i].first = people.size();//把i的左界设置为无效值
ageRange[i].second = ageRange[i – 1].second;//把i的右界设置为用户idx的最大值
}
}

for (int i = 0; i < querySum; i++)
{
int showSum, minA, maxA;
scanf("%d %d %d", &showSum, &minA, &maxA);
int sum = ageRange[maxA].second – ageRange[minA].first + 1;//求出以minA为左界,maxA为右界的people数量
printf("Case #%d:\n", i + 1);
if (sum > 0)
{//存在用户,sum的数量可能很大,用户取值<=100000,但是需要显示的数量<=100,所以用一个小根堆来维护需要显示的人
vector<PeopleNode>::iterator ite = people.begin();
priority_queue<PeopleNode, vector<PeopleNode>, cmpHeap> q;
for (int j = 0; j < sum; j++)
{
if (q.size() == showSum && q.top().netWorth <= (ite + j + ageRange[minA].first)->netWorth)
{//如果小根堆的数量已经达到显示数量,但是小根堆的顶部财富小于等于当前遍历的财富值,则压入
q.push(*((ite + j + ageRange[minA].first)));
q.pop();//相应地,弹出一个
}
else if (q.size()<showSum)//如果小根堆还没满,直接压入即可
q.push(*((ite + j + ageRange[minA].first)));

}
vector<PeopleNode> show(min(showSum, (int)q.size()));
for (int j = show.size() – 1; j >= 0; j–)
{//因为需要升序排列,用的是小根堆,所以把小根堆的堆顶放在数组尾部
show[j] = q.top();
q.pop();
}
for (int j = 0; j < show.size(); j++)
{
printf("%s %d %d\n", show[j].name, show[j].age, show[j].netWorth);
}
}
else
{//数量小于等于0,直接输出None
printf("None\n");
sum = 0;
}

}

return 0;
}
[/c]

1054. The Dominant Color (20)

1.该题求出现次数超过一半的元素,故采用moore voting算法,moore投票法。

2.遇到不同的元素,如果出现次数为0,更跟换成当前元素,如果次数不为0则-1。

3.遇到相同元素,出现次数相加。

4.最终记录的元素就是所求元素。

1054

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

Behind the scenes in the computer’s memory, color is always talked about as a series of 24 bits of information for each pixel. In an image, the color with the largest proportional area is called the dominant color. A strictly dominant color takes more than half of the total area. Now given an image of resolution M by N (for example, 800×600), you are supposed to point out the strictly dominant color.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 positive numbers: M (<=800) and N (<=600) which are the resolutions of the image. Then N lines follow, each contains M digital colors in the range [0, 224). It is guaranteed that the strictly dominant color exists for each input image. All the numbers in a line are separated by a space.

Output Specification:

For each test case, simply print the dominant color in a line.

Sample Input:

5 3
0 0 255 16777215 24
24 24 0 0 24
24 0 24 24 24

Sample Output:

24

[c language=”++”]
//#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 m, n;
cin >> m >> n;
int count = 0, color = -1;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
int tmpColor;
scanf("%d", &tmpColor);
if (color != tmpColor)
{//元素不同
if (count == 0)//更新元素
color = tmpColor;
else
count–;
}
else//元素相同,出现次数累加
count++;
}
}
cout << color << endl;
return 0;
}

[/c]

1053. Path of Equal Weight (30)

1.题目给出一棵和一个权重值W,要求求出从根到叶子节点权重累加为W的路径。

2.该题使用树节点数据结构,其中包含vector<int> child列表和权重值。

3.使用DFS进行遍历搜索(节点最多100个),能够满足要求。

1053

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

Given a non-empty tree with root R, and with weight Wi assigned to each tree node Ti. The weight of a path from R to L is defined to be the sum of the weights of all the nodes along the path from R to any leaf node L.

Now given any weighted tree, you are supposed to find all the paths with their weights equal to a given number. For example, let’s consider the tree showed in Figure 1: for each node, the upper number is the node ID which is a two-digit number, and the lower number is the weight of that node. Suppose that the given number is 24, then there exists 4 different paths which have the same given weight: {10 5 2 7}, {10 4 10}, {10 3 3 6 2} and {10 3 3 6 2}, which correspond to the red edges in Figure 1.

1053说明
Figure 1
Input Specification:

Each input file contains one test case. Each case starts with a line containing 0 < N <= 100, the number of nodes in a tree, M (< N), the number of non-leaf nodes, and 0 < S < 230, the given weight number. The next line contains N positive numbers where Wi (<1000) corresponds to the tree node Ti. Then M lines follow, each in the format:

ID K ID[1] ID[2] ... ID[K]

where ID is a two-digit number representing a given non-leaf node, K is the number of its children, followed by a sequence of two-digit ID’s of its children. For the sake of simplicity, let us fix the root ID to be 00.

Output Specification:

For each test case, print all the paths with weight S in non-increasing order. Each path occupies a line with printed weights from the root to the leaf in order. All the numbers must be separated by a space with no extra space at the end of the line.

Note: sequence {A1, A2, …, An} is said to be greater than sequence {B1, B2, …, Bm} if there exists 1 <= k < min{n, m} such that Ai = Bifor i=1, … k, and Ak+1 > Bk+1.

Sample Input:

20 9 24
10 2 4 3 5 10 2 18 9 7 2 2 1 3 12 1 8 6 2 2
00 4 01 02 03 04
02 1 05
04 2 06 07
03 3 11 12 13
06 1 09
07 2 08 10
16 1 15
13 3 14 16 17
17 2 18 19

Sample Output:

10 5 2 7
10 4 10
10 3 3 6 2
10 3 3 6 2

 
AC代码:
[c language=”++”]
//#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{
vector<int> child;
int w;
TreeNode() :child(0), w(0){};
};
void dfs(int now, int target, vector<TreeNode>&tree, vector<int>&path, vector<vector<int>>&ans)
{
if (tree[now].child.size() == 0 && target == 0)
ans.push_back(path);//叶子节点,并且满足要求
if (tree[now].child.size() != 0 && target <= 0)
return;//
else if (target < 0)
return;
for (int i = 0; i < tree[now].child.size(); i++)
{
path.push_back(tree[tree[now].child[i]].w);
dfs(tree[now].child[i], target – tree[tree[now].child[i]].w, tree, path, ans);
path.pop_back();
}
}
bool cmp(const vector<int>&a, const vector<int>&b)
{
for (int i = 0; i < min(a.size(), b.size()); i++)
{
if (a[i] >b[i])
return true;
else if (a[i] < b[i])
return false;
}
return false;
}
int main(void)
{
int nodeSum, nonLeafSum, target;
cin >> nodeSum >> nonLeafSum >> target;
vector<TreeNode> tree(nodeSum);

for (int i = 0; i < nodeSum; i++)
{
scanf("%d", &tree[i].w);
}

for (int i = 0; i < nonLeafSum; i++)
{
int nodeNum=0;
scanf("%d", &nodeNum);
int childSum = 0;
scanf("%d", &childSum);
tree[nodeNum].child = vector<int>(childSum);
for (int j = 0; j < childSum; j++)
{
scanf("%d", &tree[nodeNum].child[j]);
}
}
if (nodeSum > 0)
{
vector<int> path;
vector<vector<int>> ans;
path.push_back(tree[0].w);//注意判断根节点是否存在
target -= tree[0].w;
dfs(0, target, tree, path, ans);
sort(ans.begin(), ans.end(), cmp);
for (int i = 0; i < ans.size(); i++)
{
for (int j = 0; j < ans[i].size(); j++)
{
printf("%d", ans[i][j]);
if (j != ans[i].size() – 1)
printf(" ");
}
printf("\n");
}

}
return 0;
}

[/c]

1052. Linked List Sorting (25)

1.题目给出一些节点和其连接的下一个节点地址,求出sort后的链表。

2.这道题目主要有两个难点

1)以head为头部的链表不一样包括全部n个,即输入的数据中存在多个链表,但是我们只需要对以head为头部的链表排序输出即可,这也是为什么结果要求我们输出排序后的链表大小,因为这个大小不一定和n相等;

2)head为-1的情况,卡在这里比较久,需要特殊判断,然后输出0 -1

3.采用建立链表,然后拷贝到vector上进行排序输出。

1052

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

A linked list consists of a series of structures, which are not necessarily adjacent in memory. We assume that each structure contains an integer key and a Next pointer to the next structure. Now given a linked list, you are supposed to sort the structures according to their key values in increasing order.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive N (< 105) and an address of the head node, where N is the total number of nodes in memory and the address of a node is a 5-digit positive integer. NULL is represented by -1.

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

Address Key Next

where Address is the address of the node in memory, Key is an integer in [-105, 105], and Next is the address of the next node. It is guaranteed that all the keys are distinct and there is no cycle in the linked list starting from the head node.

Output Specification:

For each test case, the output format is the same as that of the input, where N is the total number of nodes in the list and all the nodes must be sorted order.

Sample Input:

5 00001
11111 100 -1
00001 0 22222
33333 100000 11111
12345 -1 33333
22222 1000 12345

Sample Output:

5 12345
12345 -1 00001
00001 0 11111
11111 100 22222
22222 1000 33333
33333 100000 -1

AC代码:
[c language=”++”]
//#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 ListNode{
int val, add;
ListNode*next;
ListNode() :val(0), add(0), next(NULL){};
ListNode(int x) :val(x), add(0), next(NULL){};
};
bool cmp(const ListNode&a, const ListNode&b)
{
return a.val < b.val;
}
int main(void)
{//链表可能断开,需要用头部所在的链表进行排序
int n, head;
cin >> n >> head;
vector<ListNode> list(100001);
for (int i = 0; i < n; i++)
{//读取数据
int now, val, next;
scanf("%d %d %d", &now, &val, &next);

list[now].add = now;//保存地址
list[now].val = val;//保存val
if (next != -1)
{//如果next不为-1,则有节点
list[now].next = &list[next];//进行连接
list[next].add = next;//记录next的地址
}
}
vector<ListNode> listOrder(0);//建立一个新的vector
if (head != -1)
{
ListNode* root = &list[head];//记录头部
while (root)//遍历这个链表
{
listOrder.push_back(*root);//压入节点
root = root->next;
}
sort(listOrder.begin(), listOrder.end(), cmp);

printf("%d %05d\n", listOrder.size(), listOrder[0].add);
for (int i = 0; i < listOrder.size(); i++)
{
printf("%05d %d ", listOrder[i].add, listOrder[i].val);
if (i != listOrder.size() – 1)
printf("%05d\n", listOrder[i + 1].add);
else
printf("-1\n");
}
}
else//需要对head==-1进行处理,最后一个测试点考察这个
printf("%d -1\n", listOrder.size());

return 0;
}

[/c]

1051. Pop Sequence (25)

1.这道题是判断出栈队列是否合理。

2.采用了用栈来模拟情况。

3.当目前栈为空,或者栈不为空并且栈顶不等于目标值,并且队列中还有数值可以压入,栈的size小于最大容量,那么就一直循环执行压入操作,把123456789。。。队列中的值依次压入栈,直到跳出循环。

4.跳出循环后,判断栈顶是否等于目标值,不等于的话,这个sequence就是不合理的,如果等于,则把栈顶的值pop掉,再执行步骤3。

1051

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

Given a stack which can keep M numbers at most. Push N numbers in the order of 1, 2, 3, …, N and pop randomly. You are supposed to tell if a given sequence of numbers is a possible pop sequence of the stack. For example, if M is 5 and N is 7, we can obtain 1, 2, 3, 4, 5, 6, 7 from the stack, but not 3, 2, 1, 7, 5, 6, 4.

Input Specification:

Each input file contains one test case. For each case, the first line contains 3 numbers (all no more than 1000): M (the maximum capacity of the stack), N (the length of push sequence), and K (the number of pop sequences to be checked). Then K lines follow, each contains a pop sequence of N numbers. All the numbers in a line are separated by a space.

Output Specification:

For each pop sequence, print in one line “YES” if it is indeed a possible pop sequence of the stack, or “NO” if not.

Sample Input:

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

Sample Output:

YES
NO
NO
YES
NO

 
AC代码:
[c language=”++”]
//#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 maxCap, maxSequence, querySum;
cin >> maxCap >> maxSequence >> querySum;
for (int k = 0; k < querySum; k++)
{
int idx = 1;
stack<int> sta;
int maxNum = maxCap;//栈里面能够存在的最大的值
vector<int> sequence(maxSequence);
for (int i = 0; i < maxSequence; i++)
scanf("%d", &sequence[i]);
bool result = true;

for (int i = 0; i < maxSequence; i++)
{

if (sequence[i]>maxNum)
{//不合理
result = false;
break;
}
while ((sta.empty() || (!sta.empty() && sta.top() != sequence[i])) && idx <= maxSequence && sta.size() <= maxCap)
{// 如果栈为空,或者栈不为空但是头部不等于目标值,并且还有值可以压入,队列size小于最大容量
sta.push(idx++);
}
if (sta.top() != sequence[i])
{//如果经过上面的压入操作后,仍不满足要求,则不合理
result = false;
break;
}
sta.pop();
maxNum++;//弹出了一个,可以压入更大的一个值

}
if (result)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}

[/c]

1050. String Subtraction (20)

1.给出两个string,下面string中包含的字符,需要在上面的string中删除。

2.这道题需要注意,s1和s2的输入都需要使用getline,避免出现空格的情况。

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

Given two strings S1 and S2, S = S1 – S2 is defined to be the remaining string after taking all the characters in S2 from S1. Your task is simply to calculate S1 – S2 for any given strings. However, it might not be that simple to do it fast.

Input Specification:

Each input file contains one test case. Each case consists of two lines which gives S1 and S2, respectively. The string lengths of both strings are no more than 104. It is guaranteed that all the characters are visible ASCII codes and white space, and a new line character signals the end of a string.

Output Specification:

For each test case, print S1 – S2 in one line.

Sample Input:

They are students.
aeiou

Sample Output:

Thy r stdnts.

 
AC代码:
[c language=”++”]
//#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 s1, s2;
getline(cin, s1);
getline(cin, s2);//注意s2也需要geline,可能包括空格
bool exist[256] = { 0 };
for (int i = 0; i<s2.size(); i++)
{
exist[s2[i]] = true;
}
string ans = "";
for (int i = 0; i<s1.size(); i++)
{
if (!exist[s1[i]])
ans += s1[i];
}
cout << ans << endl;
return 0;
}

[/c]

1049. Counting Ones (30)

1.和leetcode里面的Number of Digit One一样,统计0~n中,出现多少个1.

2.算法说明:

如3141592,在m(digitDivide)=100时,即要求计算百位上“1”的个数

其中a为31415,b为92,31415中出现了3142次“1”,因为每10个数里面出现1次“1”。而实际上,31415是3141500,所以把31415中1的个数再乘以m。如3141400~3141499中,前缀为31414的数出现了100次,所以需要乘以m(此时是100)。

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

The task is simple: given any positive integer N, you are supposed to count the total number of 1’s in the decimal form of the integers from 1 to N. For example, given N being 12, there are five 1’s in 1, 10, 11, and 12.

Input Specification:

Each input file contains one test case which gives the positive N (<=230).

Output Specification:

For each test case, print the number of 1’s in one line.

Sample Input:

12

Sample Output:

5

AC代码:
[c language=”++”]
#include <iostream>
#include <stdio.h>
#include <vector>
#include <stack>
#include <algorithm>
#include <memory.h>
#include <map>
#include <set>
#include "limits.h"
using namespace std;

int main(void)
{
long long n;
cin>>n;
long long ans = 0;
for(long long digitDivide=1;digitDivide<=n;digitDivide*=10)
{
long long a = n / digitDivide;
long long b = n%digitDivide;
ans+=(a+8)/10*digitDivide+(a%10==1)*(b+1);
}
cout<<ans<<endl;

return 0;
}
[/c]
 

1048. Find Coins (25)

1.和leetcode的two sum一样,找出两个coin,使其价值等于amount。

2.采用哈希表记录已经遍历过的数据,target=pay-num[i],查找num[target]是否在哈希表中有,如果有,则压进ans容器,最后进行排序输出。

3.时间复杂度为o(n)。

1048find coins

 

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

Eva loves to collect coins from all over the universe, including some other planets like Mars. One day she visited a universal shopping mall which could accept all kinds of coins as payments. However, there was a special requirement of the payment: for each bill, she could only use exactly two coins to pay the exact amount. Since she has as many as 105 coins with her, she definitely needs your help. You are supposed to tell her, for any given amount of money, whether or not she can find two coins to pay for it.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 positive numbers: N (<=105, the total number of coins) and M(<=103, the amount of money Eva has to pay). The second line contains N face values of the coins, which are all positive numbers no more than 500. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in one line the two face values V1 and V2 (separated by a space) such that V1 + V2 = M and V1 <= V2. If such a solution is not unique, output the one with the smallest V1. If there is no solution, output “No Solution” instead.

Sample Input 1:

8 15
1 2 8 7 2 4 11 15

Sample Output 1:

4 11

Sample Input 2:

7 14
1 8 7 2 4 11 15

Sample Output 2:

No Solution

 

AC代码如下:
[c language=”++”]
#include <iostream>
#include <stdio.h>
#include <vector>
#include <stack>
#include <algorithm>
#include <memory.h>
#include <map>
#include <set>
#include "limits.h"
using namespace std;
/*
8 15
1 2 8 7 2 4 11 15

7 14
1 8 7 2 4 11 15
*/
bool cmp(const pair<int,int>&a,const pair<int,int>&b)
{
return a.first<b.first;
}

int main(void)
{
int coinSum,pay;
scanf("%d %d",&coinSum,&pay);
int *coin=new int[coinSum];
int target;
int *haveCoin=new int[501];
memset(haveCoin, 0, sizeof(haveCoin));
vector<pair<int,int>> ans(0);
for(int i=0;i<coinSum;i++)
{
scanf("%d",&coin[i]);
target=pay-coin[i];
if(target>=0&&target<=500&&haveCoin[target]>0)
{
int a=min(coin[i],target);
int b=pay-a;
ans.push_back({a,b});
}
haveCoin[coin[i]]++;
}
sort(ans.begin(),ans.end(),cmp);
if(ans.size()>0)
printf("%d %d\n",ans[0].first,ans[0].second);
else
printf("No Solution\n");
return 0;
}

[/c]

1047. Student List for Course (25)

1.和前面的1039 Course List for Student (25) 相类似,但是这次给出学生选的课程数,求每个课程有多少学生选,分别是谁。

2.刚开始使用vector<set<int>> 格式存储course,后面在输入数据的时候就已经超时。

3.随后改为vector<vector<int>> 存储,在后面进行sort,没有超时。

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

Zhejiang University has 40000 students and provides 2500 courses. Now given the registered course list of each student, you are supposed to output the student name lists of all the courses.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 numbers: N (<=40000), the total number of students, and K (<=2500), the total number of courses. Then N lines follow, each contains a student’s name (3 capital English letters plus a one-digit number), a positive number C (<=20) which is the number of courses that this student has registered, and then followed by C course numbers. For the sake of simplicity, the courses are numbered from 1 to K.

Output Specification:

For each test case, print the student name lists of all the courses in increasing order of the course numbers. For each course, first print in one line the course number and the number of registered students, separated by a space. Then output the students’ names in alphabetical order. Each name occupies a line.

Sample Input:

10 5
ZOE1 2 4 5
ANN0 3 5 2 1
BOB5 5 3 4 2 1 5
JOE4 1 2
JAY9 4 1 2 5 4
FRA8 3 4 2 5
DON2 2 4 5
AMY7 1 5
KAT3 3 5 4 2
LOR6 4 2 4 1 5

Sample Output:

1 4
ANN0
BOB5
JAY9
LOR6
2 7
ANN0
BOB5
FRA8
JAY9
JOE4
KAT3
LOR6
3 1
BOB5
4 7
BOB5
DON2
FRA8
JAY9
KAT3
LOR6
ZOE1
5 9
AMY7
ANN0
BOB5
DON2
FRA8
JAY9
KAT3
LOR6
ZOE1

 

AC代码如下:
[c language=”++”]
//#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 studentSum, courseSum;
scanf("%d %d", &studentSum, &courseSum);
char name[5];
vector<vector<int>> course(courseSum);
int *courseIdx = new int[20];
int nameInt;
int chooseSum;
for (int i = 0; i<studentSum; i++)
{//输入学生即其所选的课程
scanf("%s", name);
nameInt = (name[0] – ‘A’) * 26 * 26 * 10 + (name[1] – ‘A’) * 26 * 10 + (name[2] – ‘A’) * 10 + (name[3] – ‘0’);
scanf("%d", &chooseSum);
for (int j = 0; j<chooseSum; j++)
{
scanf("%d", &courseIdx[j]);
course[courseIdx[j] – 1].push_back(nameInt);
}
}
for (int i = 0; i<course.size(); i++)
{//输出各门课程的结果
printf("%d %d\n", i + 1, course[i].size());
sort(course[i].begin(), course[i].end());
for (vector<int>::iterator ite = course[i].begin(); ite != course[i].end(); ite++)
{//转化学生的名字,进行输出
name[4] = 0;
name[3] = (*ite) % 10 + ‘0’;
name[2] = ((*ite) / 10) % 26 + ‘A’;
name[1] = ((*ite) / 10 / 26) % 26 + ‘A’;
name[0] = ((*ite) / 10 / 26 / 26) + ‘A’;
printf("%s\n", name);
}
}

return 0;
}

[/c]