1007. Maximum Subsequence Sum (25)

1.题目要求最大的连续自序列和,如果全为负数,则输出0,首位,末位;如果不为负数,则输出总和,子序列的第一位,子序列的最后一位。

2.注意判断全为负数的情况,第一个数是否为负数,不要漏判断。(刚开始漏判断了)

3.实际上采用动态规划,dp[i]=max{dp[i-1]+num[i],num[i]},dp[i]一定会包含当前的数字num[i],但是可以简化为判断dp[i-1]是否为负数。

Given a sequence of K integers { N1, N2, …, NK }. A continuous subsequence is defined to be { Ni, Ni+1, …, Nj } where 1 <= i <= j <= K. The Maximum Subsequence is the continuous subsequence which has the largest sum of its elements. For example, given sequence { -2, 11, -4, 13, -5, -2 }, its maximum subsequence is { 11, -4, 13 } with the largest sum being 20.

Now you are supposed to find the largest sum, together with the first and the last numbers of the maximum subsequence.

Input Specification:

Each input file contains one test case. Each case occupies two lines. The first line contains a positive integer K (<= 10000). The second line contains K numbers, separated by a space.

Output Specification:

For each test case, output in one line the largest sum, together with the first and the last numbers of the maximum subsequence. The numbers must be separated by one space, but there must be no extra space at the end of a line. In case that the maximum subsequence is not unique, output the one with the smallest indices i and j (as shown by the sample case). If all the K numbers are negative, then its maximum sum is defined to be 0, and you are supposed to output the first and the last numbers of the whole sequence.

Sample Input:

10
-10 1 2 3 4 -5 -23 3 7 -21

Sample Output:

10 1 4

[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>
using namespace std;
int main(void) {

int n;
cin >> n;
if (n == 0)
{
cout << "0 0 0" << endl;
return 0;
}
long long *num = new long long[n];
for (int i = 0; i < n; i++)
{
cin >> num[i];
}
//使用pair,first代表从那个i开始,second表示从i加到当前数字的综合
vector<pair<int, long long>> dp(n, { 0, 0 });
dp[0].first = 0;
dp[0].second = num[0];
bool negative = true;
if (num[0] >= 0) negative = false;//注意第一个数也要判断正负
for (int i = 1; i < n; i++)
{
if (negative&&num[i] >= 0) negative = false;//判断是否全负数
if (dp[i – 1].second <= 0)
{//如果dp[i-1]小于0,那么num[i]加上它肯定小于num[i],所以不加
dp[i].first = i;
dp[i].second = num[i];
}
else
{//如果dp[i-1]大于等于0,那么num[i]加上它肯定大于等于num[i],所以需要加上
dp[i].first = dp[i – 1].first;
dp[i].second = dp[i – 1].second + num[i];
}

}

if (negative)
{//如果全为负数,则输出首尾两个数
cout << 0 << " " << num[0] << " " << num[n – 1] << endl;
}
else
{
long long maxAns = -1; int index = -1;
for (int i = 0; i < n; i++)
{//遍历一遍,找出second最大的dp
if (maxAns < dp[i].second)
{
maxAns = dp[i].second;
index = i;
}
}
//根据题目要求输出最大的和,和相当一序列起始值和结束值
cout << dp[index].second << " " << num[dp[index].first] << " " << num[index] << endl;
}

return 0;
}
[/c]

1006. Sign In and Sign Out (25)

1.采用algorithm.h里面的sort函数,对时间进行排序,需要重写比较函数。
2.计算最早到时,通过到达时间前后进行排序。
3.计算最晚走时,通过离开时间的晚早进行排序。

At the beginning of every day, the first person who signs in the computer room will unlock the door, and the last one who signs out will lock the door. Given the records of signing in’s and out’s, you are supposed to find the ones who have unlocked and locked the door on that day.

Input Specification:

Each input file contains one test case. Each case contains the records for one day. The case starts with a positive integer M, which is the total number of records, followed by M lines, each in the format:

ID_number Sign_in_time Sign_out_time

where times are given in the format HH:MM:SS, and ID number is a string with no more than 15 characters.

Output Specification:

For each test case, output in one line the ID numbers of the persons who have unlocked and locked the door on that day. The two ID numbers must be separated by one space.

Note: It is guaranteed that the records are consistent. That is, the sign in time must be earlier than the sign out time for each person, and there are no two persons sign in or out at the same moment.

Sample Input:

3
CS301111 15:30:28 17:00:10
SC3021234 08:00:00 11:25:25
CS301133 21:45:00 21:58:40

Sample Output:

SC3021234 CS301133

[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>
using namespace std;
int time2Int(string s)
{
int hour = (s[0] – ‘0’) * 10 + s[1] – ‘0’;
int min = (s[3] – ‘0’) * 10 + s[4] – ‘0’;
int sec = (s[6] – ‘0’) * 10 + s[7] – ‘0’;
return hour * 3600 + min * 60 + sec;
}
struct people{
int begin, end;
string ID;
people() :begin(0), end(0), ID(""){};
};
bool cmpBegin(const people&a, const people&b)
{
if (a.begin < b.begin) return true;
else return false;
}
bool cmpEnd(const people&a, const people&b)
{
if (a.end > b.end) return true;
else return false;
}
int main(void) {

int n;
cin >> n;
vector<people> p(n);
for (int i = 0; i < n; i++)
{
string a, b, c;
cin >> a >> b >> c;
p[i].ID = a;
p[i].begin = time2Int(b);
p[i].end = time2Int(c);
}
string first = "";
sort(p.begin(), p.end(), cmpBegin);
first = p[0].ID;
sort(p.begin(), p.end(), cmpEnd);
string last = p[0].ID;
cout << first << " " << last << endl;
return 0;
}
[/c]

1005. Spell It Right (20)

1.主要是string的位操作,string的每一位都是一个char

Given a non-negative integer N, your task is to compute the sum of all the digits of N, and output every digit of the sum in English.

Input Specification:

Each input file contains one test case. Each case occupies one line which contains an N (<= 10100).

Output Specification:

For each test case, output in one line the digits of the sum in English words. There must be one space between two consecutive words, but no extra space at the end of a line.

Sample Input:

12345

Sample Output:

one five

 

[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>
using namespace std;

int main(void) {

string str;
cin >> str;
int sum = 0;
for (int i = 0; i < str.size(); i++)
{
sum += str[i] – ‘0’;//直接进行各位的累加
}
string int2Str[10] = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };

str = "";
string ans = "";
if (sum == 0) ans = "zero";
while (sum != 0)
{
char c = sum % 10 + ‘0’;
str = c + str;
sum /= 10;
}
for (int i = 0; i < str.size(); i++)
{
ans += int2Str[str[i] – ‘0’];
if (i != str.size() – 1)
ans += " ";
}
cout << ans << endl;

return 0;
}
[/c]

 

1004. Counting Leaves (30)

1.题目要求计算家族树中,每层叶子节点的数量(即没有后代的人的个数)。

2.可为多叉树,采用vector<string>保存子树名称。

3.采用map记录树节点。

4.采用广度遍历,输出每层的叶子节点数量。

节点代码如下:

[c language=”++”]
struct node{
vector<string> child;
int head;
string ID;
node() :head(-1), child(0), ID(""){};
};
[/c]

A family hierarchy is usually presented by a pedigree tree. Your job is to count those family members who have no child.

Input

Each input file contains one test case. Each case starts with a line containing 0 < N < 100, the number of nodes in a tree, and M (< N), the number of non-leaf nodes. 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 01.

Output

For each test case, you are supposed to count those family members who have no child for every seniority level starting from the root. The numbers must be printed in a line, separated by a space, and there must be no extra space at the end of each line.

The sample case represents a tree with only 2 nodes, where 01 is the root and 02 is its only child. Hence on the root 01 level, there is 0 leaf node; and on the next level, there is 1 leaf node. Then we should output “0 1” in a line.

Sample Input

2 1
01 1 02

Sample Output

0 1

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>
using namespace std;
#define maxDist 999999
struct node{
vector<string> child;
int head;
string ID;
node() :head(-1), child(0), ID(""){};
};

int main(void) {

int n, m;
cin >> n >> m;

map<string, node> tree;
for (int i = 0; i < m; i++)
{//循环输入父子关系
string ID;
cin >> ID;
tree[ID].ID = ID;
int k;
cin >> k;
for (int i = 0; i < k; i++)
{
string tmp;
cin >> tmp;
if (tmp.size() == 1)
tmp = "0" + tmp;//避免出现单位的数字如1,2,3,4;题目要求是两位数,所以是01,02,03,04
tree[ID].child.push_back(tmp);
tree[tmp].ID = tmp;
tree[tmp].head++;
}
}
//需要建立一个前头节点,便于循环计算
tree["superhead"].ID = "";
tree["superhead"].child = vector<string>(0);
tree["superhead"].head = 100;
string headID = "";
tree["superhead"].child.push_back("01");
headID = "superhead";
queue<string> q;
q.push(headID);
vector<int> ans(0);
int count1 = 1;
int count2 = 0;
int leaf = 0;
while (!q.empty())
{
for (int k = 0; k < count1; k++)
{//上一层有count1个
string top = q.front();
q.pop();
for (int i = 0; i < tree[top].child.size(); i++)
{
string tmp = tree[top].child[i];
if (tree[tmp].child.size() == 0)
leaf++;//如果没有子节点,那么就是叶子节点
else
{
q.push(tmp);//有子节点,压进队列,继续遍历
count2++;
}
}
}
ans.push_back(leaf);
leaf = 0;
count1 = count2;
count2 = 0;
}
for (int i = 0; i < ans.size(); i++)
{
cout << ans[i];
if (i != ans.size() – 1)
cout << " ";
}
return 0;
}
[/c]

1003. Emergency (25)

1.求源城市s到目标城市t的最小耗费路径,如果路径不唯一,则输出具有最多救援队的路径。

2.采用dijkstra算法,算出最小耗费cost。

3.利用最小耗费cost最为约束条件,进行深度搜索DFS(循环->锁->dfs->解锁)。

As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several scattered cities connected by some roads. Amount of rescue teams in each city and the length of each road between any pair of cities are marked on the map. When there is an emergency call to you from some other city, your job is to lead your men to the place as quickly as possible, and at the mean time, call up as many hands on the way as possible.

Input

Each input file contains one test case. For each test case, the first line contains 4 positive integers: N (<= 500) – the number of cities (and the cities are numbered from 0 to N-1), M – the number of roads, C1 and C2 – the cities that you are currently in and that you must save, respectively. The next line contains N integers, where the i-th integer is the number of rescue teams in the i-th city. Then M lines follow, each describes a road with three integers c1, c2 and L, which are the pair of cities connected by a road and the length of that road, respectively. It is guaranteed that there exists at least one path from C1 to C2.

Output

For each test case, print in one line two numbers: the number of different shortest paths between C1 and C2, and the maximum amount of rescue teams you can possibly gather.
All the numbers in a line must be separated by exactly one space, and there is no extra space allowed at the end of a line.

Sample Input

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

Sample Output

2 4

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>
using namespace std;
#define maxDist 999999
struct vertexNode{
vector<int> list;
bool visited, sured;
int pre;
int cost;
};
struct cmp{
bool operator()(const pair<int, int>&a, const pair<int, int>&b)
{
return a.second > b.second;
}
};

void dfs(int now, int&target, vertexNode *v, int **w, int*rescue, vector<bool>&used, int &minCost, vector<int>&ans, int nowCost, int rescueTeam)
{
if (now == target&&minCost == nowCost)
{
ans.push_back(rescueTeam);
}
else
{
for (int i = 0; i < v[now].list.size(); i++)
{
int q = v[now].list[i];
if (!used[q] && nowCost + w[now][q] <= minCost)
{//以最小耗费为约束条件
used[q] = true;
dfs(q, target, v, w, rescue, used, minCost, ans, nowCost + w[now][q], rescueTeam + rescue[q]);
used[q] = false;
}
}
}
}

int main(void) {

int n, m, s, t;
cin >> n >> m >> s >> t;

int *rescue = new int[n];
int *cost = new int[n];

for (int i = 0; i < n; i++)
{
scanf("%d", &rescue[i]);//输出各城市的救援队数目
cost[i] = 99999999;//初始化cost
}

int **w = new int*[n];

vertexNode *v = new vertexNode[n];
for (int i = 0; i < n; i++)
{
w[i] = new int[n];
memset(w[i], 0, sizeof(w[i]));
v[i].cost = 99999999;
v[i].pre = -1;
v[i].list = vector<int>(0);
v[i].sured = false;
v[i].visited = false;
}

for (int i = 0; i < m; i++)
{
int a, b, weight;
scanf("%d %d %d", &a, &b, &weight);
v[a].list.push_back(b);
v[b].list.push_back(a);
w[a][b] = weight;
w[b][a] = weight;
}

v[s].visited = true;
v[s].pre = -1;
v[s].cost = 0;
while (1)
{//采用dijkstra算法计算最小耗费
int p = -1;
for (int i = 0; i < n; i++)
{
if (p == -1 && v[i].visited&&!v[i].sured)
p = i;
else if (p != -1 && v[i].visited&&!v[i].sured&&v[p].cost > v[i].cost)
p = i;
}
if (p == -1) break;
v[p].sured = true;
for (int i = 0; i < v[p].list.size(); i++)
{
int q = v[p].list[i];
if (!v[q].visited)
{
v[q].cost = v[p].cost + w[p][q];
v[q].visited = true;
v[q].pre = p;
}
else if (v[q].visited&&!v[q].sured&&v[q].cost > v[p].cost + w[p][q])
{
v[q].cost = v[p].cost + w[p][q];
v[q].visited = true;
v[q].pre = p;
}
}
}
int minCost = v[t].cost;
vector<bool> used(n, false);
vector<int> ans(0);
used[s] = true;
dfs(s, t, v, w, rescue, used, minCost, ans, 0, rescue[s]);

sort(ans.begin(), ans.end());
cout << ans.size() << " " << ans.back() << endl;

return 0;
}
[/c]

1002. A+B for Polynomials (25)

1.直接建立1001长度的数组,分别进行存储,最后累加输出。

This time, you are supposed to find A+B where A and B are two polynomials.

Input

Each input file contains one test case. Each case occupies 2 lines, and each line contains the information of a polynomial: K N1 aN1 N2 aN2 … NK aNK, where K is the number of nonzero terms in the polynomial, Ni and aNi (i=1, 2, …, K) are the exponents and coefficients, respectively. It is given that 1 <= K <= 10,0 <= NK < … < N2 < N1 <=1000.

Output

For each test case you should output the sum of A and B in one line, with the same format as the input. Notice that there must be NO extra space at the end of each line. Please be accurate to 1 decimal place.

Sample Input

2 1 2.4 0 3.2
2 2 1.5 1 0.5

Sample Output

3 2 1.5 1 2.9 0 3.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;

int main(void)
{
vector<float> N1(1002, 0);
vector<float> N2(1002, 0);
int n, m;
cin >> n;
//输入第一个多项式
for (int i = 0; i < n; i++)
{
int idx = 0;
cin >> idx;
cin >> N1[idx];
}

cin >> m;
//输入第二个多项式
for (int i = 0; i < m; i++)
{
int idx = 0;
cin >> idx;
cin >> N2[idx];
}

//同阶的系数相加
for (int i = 0; i < N1.size(); i++)
{
N1[i] = N1[i] + N2[i];
}

int sum = 0;
for (int i = 0; i < N1.size(); i++)
{
if (N1[i] != 0)
sum++;
}
cout << sum;
for (int i = N1.size() – 1; i >= 0; i–)
{//高位先输出
if (N1[i] != 0)//不为0,则输出
printf(" %d %.1f", i, N1[i]);
}
return 0;
}
[/c]

1001. A+B Format (20)

1.主要是字符串处理,然后插入逗号

2.注意正负数

3.输入可以直接使用int类型读取

Calculate a + b and output the sum in standard format — that is, the digits must be separated into groups of three by commas (unless there are less than four digits).

Input

Each input file contains one test case. Each case contains a pair of integers a and b where -1000000 <= a, b <= 1000000. The numbers are separated by a space.

Output

For each test case, you should output the sum of a and b in one line. The sum must be written in the standard format.

Sample Input

-1000000 9

Sample Output

-999,991

 

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 a, b;
cin >> a >> b;
int result = a + b;
bool sign = true;//正负符号标志位
if (result < 0)
{
result = -result;
sign = false;
}
string str = "";
if (result == 0) str = "0";
while (result != 0)
{//转化成string
char c = result % 10 + ‘0’;
str += c;
result /= 10;
}

//此时的str是倒序的
string output = "";
for (int i = 0; i < str.size() – 1; i++)
{
output = str[i] + output;
if ((i+1) % 3 == 0)
output = ‘,’ + output;
}
output = str[str.size() – 1] + output;
if (!sign) output = "-" + output;
cout << output << endl;

return 0;
}
[/c]