1046. Shortest Distance (20)

1.给出一个数组,求出0到i点的最短距离,可以直接从0->1->2->…->i,也可以0->n-1->n-2->n-3->…->i+1->i。

2.建立一个数组dp[i],记录0到i之间的距离和。

3.定义sum,记录全程的路程。

4.求i,j的最短距离时,利用ans=dp[j]-[i]+num[i]-num[j],ans2=sum-ans,min(ans,ans2)即为答案。

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

The task is really simple: given N exits on a highway which forms a simple cycle, you are supposed to tell the shortest distance between any pair of exits.

Input Specification:

Each input file contains one test case. For each case, the first line contains an integer N (in [3, 105]), followed by N integer distances D1 D2 … DN, where Di is the distance between the i-th and the (i+1)-st exits, and DN is between the N-th and the 1st exits. All the numbers in a line are separated by a space. The second line gives a positive integer M (<=104), with M lines follow, each contains a pair of exit numbers, provided that the exits are numbered from 1 to N. It is guaranteed that the total round trip distance is no more than 107.

Output Specification:

For each test case, print your results in M lines, each contains the shortest distance between the corresponding given pair of exits.

Sample Input:

5 1 2 4 14 9
3
1 3
2 5
4 1

Sample Output:

3
10
7

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)
{

int n;
scanf("%d",&n);
int *num=new int[n];
int *dp=new int[n];
memset(dp, 0, sizeof(dp));
int sum=0;
for(int i=0;i<n;i++)
{
scanf("%d",&num[i]);
if(i==0) dp[i]=num[i];
else dp[i]=dp[i-1]+num[i];
sum+=num[i];
}
int m;
scanf("%d",&m);
for(int i=0;i<m;i++)
{
int a,b;
scanf("%d %d",&a,&b);
if(a>b) swap(a,b);
int tmp=dp[b-1]-dp[a-1]+num[a-1]-num[b-1];
int tmp2=sum-tmp;
printf("%d\n",min(tmp2,tmp));
}
return 0;
}

[/c]

1045. Favorite Color Stripe (30)

1.这个和最长公共子序列问题相类似(LCS),给出目标字符串,求出在t中求出符合顺序和颜色要求的最长子字符串(可以省去目标字符串中的一些颜色)。

2.不同的地方是允许元素重复,如{a}和{aaa},匹配出来的是3,a可以重复3次。

3.该问题一开始卡在了输入格式上。

4.动态规划方程:dp[i][j]表示f[0~i]与o[0~j]匹配的最大长度。

如果f[i]==o[j],dp[i][j]=max(dp[i][j-1]+1,dp[i-1][j-1]),当目前颜色相同,在上一个的基础上+1(表示上一次已经使用f[i]进行匹配),或者在dp[i-1][j-1]上+1(表示这次才开始使用f[i]作为匹配);

如果f[i]!=o[j],dp[i][j]=max(dp[i][j-1],dp[i-1][j]),当目前的颜色不相同,那么选取dp[i][j-1](f[i]已经进行匹配)和dp[i-1][j](f[i]未进行匹配)的最大值。

5.还有一种最简单的方法:dp[i][j]=max(dp[i-1][j],dp[i][j-1],dp[i-1][j-1]),如果f[i]==o[j],则dp[i][j]++:(采用了LCS的思想)

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

Eva is trying to make her own color stripe out of a given one. She would like to keep only her favorite colors in her favorite order by cutting off those unwanted pieces and sewing the remaining parts together to form her favorite color stripe.

It is said that a normal human eye can distinguish about less than 200 different colors, so Eva’s favorite colors are limited. However the original stripe could be very long, and Eva would like to have the remaining favorite stripe with the maximum length. So she needs your help to find her the best result.

Note that the solution might not be unique, but you only have to tell her the maximum length. For example, given a stripe of colors {2 2 4 1 5 5 6 3 1 1 5 6}. If Eva’s favorite colors are given in her favorite order as {2 3 1 5 6}, then she has 4 possible best solutions {2 2 1 1 1 5 6}, {2 2 1 5 5 5 6}, {2 2 1 5 5 6 6}, and {2 2 3 1 1 5 6}.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<=200) which is the total number of colors involved (and hence the colors are numbered from 1 to N). Then the next line starts with a positive integer M (<=200) followed by M Eva’s favorite color numbers given in her favorite order. Finally the third line starts with a positive integer L (<=10000) which is the length of the given stripe, followed by L colors on the stripe. All the numbers in a line are separated by a space.

Output Specification:

For each test case, simply print in a line the maximum length of Eva’s favorite stripe.

Sample Input:

6
5 2 3 1 5 6
12 2 2 4 1 5 5 6 3 1 1 5 6

Sample Output:

7

 
简单方法的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;
/*
6
5 2 3 1 5 6
12 2 2 4 1 5 5 6 3 1 1 5 6

6
5 2 3 1 5 6
10 2 2 3 1 3 1 3 1 3 1

6
5 2 3 1 5 6
10
5 6 6 6 6 6 6 6 6 6 6

6
5 2 3 1 5 6
10
2 6 6 6 6 6 6 6 6 6 6

6
5 2 3 1 5 6
10
2 2 2 6 6 6 6 6 6 6 6

6
5 2 3 1 5 6
10
2 2 2 6 6 6 6 5 6 6 6

6
5 2 3 1 5 6
10
2 2 2 6 6 6 6 6 5 6 6
*/
int main(void)
{
int colourSum,fnum, onum;
cin >> colourSum>> fnum;
vector<int> f(fnum);
for (int i = 0; i<fnum; i++)
{
scanf("%d", &f[i]);
}
cin >> onum;
vector<int> o(onum);

for (int i = 0; i<onum; i++)
{
scanf("%d", &o[i]);
}

vector<vector<int>> dp(fnum+1, vector<int>(onum+1,0));

int thisMax = 0;
for (int i = 1; i<=f.size(); i++)
{
for (int j = 1; j<=o.size(); j++)
{
dp[i][j] = max(max(dp[i – 1][j], dp[i][j – 1]), dp[i-1][j-1]);
if (f[i-1] == o[j-1])
dp[i][j]++;
}
}
cout << dp[fnum][onum] << endl;
return 0;
}

[/c]

第一种方法的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;
/*
6
5
2 3 1 5 6
12 2 2 4 1 5 5 6 3 1 1 5 6

4
5
2 3 1 5 6
10 2 2 3 1 3 1 3 1 3 1

2
5
2 3 1 5 6
10
5 6 6 6 6 6 6 6 6 6 6

2
5
2 3 1 5 6
10
2 6 6 6 6 6 6 6 6 6 6

2
5
2 3 1 5 6
10
2 2 2 6 6 6 6 6 6 6 6
*/
int main(void)
{
int colorSum,fnum, onum;
cin >> colorSum>> fnum;
vector<int> f(fnum);
for (int i = 0; i<fnum; i++)
{//输入喜欢的颜色
scanf("%d", &f[i]);
}
cin >> onum;
vector<int> o(onum);

for (int i = 0; i<onum; i++)
{//输入源材料
scanf("%d", &o[i]);
}

vector<vector<int>> dp(fnum, vector<int>(onum));
for (int i = 0; i<f.size(); i++)
{//初始化边界数组
if (f[i] == o[0])
dp[i][0] = 1;
else if (i == 0)
dp[i][0] = 0;
else
dp[i][0] = dp[i – 1][0];
}

for (int i = 0; i<f.size(); i++)
{
for (int j = 1; j<o.size(); j++)
{
if (f[i] == o[j])
{//如果相等,那么dp[i][j]由dp[i][j-1]和dp[i-1][j-1]的最大值构成
if (i != 0)
dp[i][j] = max(dp[i][j – 1] + 1, dp[i – 1][j – 1] + 1);
else
dp[i][j] = dp[i][j – 1] + 1;
}
else
{
if (i != 0)
dp[i][j] = max(dp[i][j – 1], dp[i – 1][j]);//取包含上一个f的长度和不包含上一个f的长度两者最大值
else
dp[i][j] = dp[i][j – 1];
}
}
}
cout << dp[fnum – 1][onum – 1] << endl;
return 0;
}
[/c]

1044. Shopping in Mars (25)

1.题目要求在一个数组中,找出等于amount的连续子序列和,如果不存在等于的,则找出大于amount的最小子序列的和。

2.使用尺取法,如果取得范围总和大于需要pay的,删掉头部。

3.如果取得范围综合小于pay的,增加尾部。

4.注意边界情况和没有相等的情况,细节可查看代码。

5.利用一个minAns的变量进行记录答案数值。

部分测试用例:

[c language=”++”]
16 15
3 2 1 5 4 6 8 7 16 10 15 11 9 12 14 13

5 13
2 4 5 7 9

10 1
2 3 4 5 6 1 2 3 4 6

10 1
2 3 4 5 1 1 2 1 1 1
ans:
5-5
6-6
8-8
9-9
10-10

10 0
2 3 4 5 1 1 2 1 1 1
ans:
5-5
6-6
8-8
9-9
10-10

10 -1
2 3 4 5 1 1 2 1 1 1
ans:
5-5
6-6
8-8
9-9
10-10
[/c]

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

Shopping in Mars is quite a different experience. The Mars people pay by chained diamonds. Each diamond has a value (in Mars dollars M$). When making the payment, the chain can be cut at any position for only once and some of the diamonds are taken off the chain one by one. Once a diamond is off the chain, it cannot be taken back. For example, if we have a chain of 8 diamonds with values M$3, 2, 1, 5, 4, 6, 8, 7, and we must pay M$15. We may have 3 options:

1. Cut the chain between 4 and 6, and take off the diamonds from the position 1 to 5 (with values 3+2+1+5+4=15).
2. Cut before 5 or after 6, and take off the diamonds from the position 4 to 6 (with values 5+4+6=15).
3. Cut before 8, and take off the diamonds from the position 7 to 8 (with values 8+7=15).

Now given the chain of diamond values and the amount that a customer has to pay, you are supposed to list all the paying options for the customer.

If it is impossible to pay the exact amount, you must suggest solutions with minimum lost.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 numbers: N (<=105), the total number of diamonds on the chain, and M (<=108), the amount that the customer has to pay. Then the next line contains N positive numbers D1 … DN (Di<=103 for all i=1, …, N) which are the values of the diamonds. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print “i-j” in a line for each pair of i <= j such that Di + … + Dj = M. Note that if there are more than one solution, all the solutions must be printed in increasing order of i.

If there is no solution, output “i-j” for pairs of i <= j such that Di + … + Dj > M with (Di + … + Dj – M) minimized. Again all the solutions must be printed in increasing order of i.

It is guaranteed that the total value of diamonds is sufficient to pay the given amount.

Sample Input 1:

16 15
3 2 1 5 4 6 8 7 16 10 15 11 9 12 14 13

Sample Output 1:

1-5
4-6
7-8
11-11

Sample Input 2:

5 13
2 4 5 7 9

Sample Output 2:

2-4
4-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;

/*
16 15
3 2 1 5 4 6 8 7 16 10 15 11 9 12 14 13

5 13
2 4 5 7 9

10 1
2 3 4 5 6 1 2 3 4 6

10 1
2 3 4 5 1 1 2 1 1 1
ans:
5-5
6-6
8-8
9-9
10-10

10 0
2 3 4 5 1 1 2 1 1 1
ans:
5-5
6-6
8-8
9-9
10-10

10 -1
2 3 4 5 1 1 2 1 1 1
ans:
5-5
6-6
8-8
9-9
10-10
*/
bool cmp(const pair<int,pair<int,int>>&a,const pair<int,pair<int,int>>&b)
{
if(a.first<b.first)
return true;
else if(a.first==b.first&&a.second.first<b.second.first)
return true;
else return false;
}
int main(void)
{
int sum,pay;
scanf("%d %d",&sum,&pay);
vector<int> diamonds(sum);
for(int i=0;i<sum;i++)
{
scanf("%d",&diamonds[i]);
}
int i=0,j=0;
int value=diamonds[0];//默认输入的数组大于0
int minAns=INT_MAX;
vector<pair<int,pair<int,int>>> ans(0);
while(1)
{
if(value==pay&&i<=j)
{//加入i<=j,避免出现2-1,6-4之类的,j小于i的情况
minAns=min(minAns,value);
ans.push_back({value,{i+1,j+1}});
value-=diamonds[i++];
}
else if(value>pay&&i<=j)
{//加入i<=j,避免出现2-1,6-4之类的,j小于i的情况
if(value<=minAns)
{//value>pay && value<=minAns,所以 pay<value<=minAns,minAns>pay
minAns=value;
ans.push_back({value,{i+1,j+1}});
}
value-=diamonds[i++];

}
else//value<pay
{
j++;
if(j<diamonds.size())
value+=diamonds[j];
else
break;
}
}
sort(ans.begin(), ans.end(), cmp);
for(int k=0;k<ans.size();k++)
{
if(ans[k].first==minAns)
printf("%d-%d\n",ans[k].second.first,ans[k].second.second);
else break;
}

return 0;
}
[/c]

1043. Is It a Binary Search Tree (25)

1.题目给出一个前序遍历的数组,要求判断是否是BST或者是镜像的BST,如果是,则输出它的层次遍历。

2.写两个函数,分别用来建立正常的BST:dfs和镜像BST:dfsMirror。这样就不用在检查的时候进行判断。

3.如果使用dfs不能建立BST,那么使用dfsMirror进行建立,两者都不能建立,则输出NO。

时间限制
400 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.

If we swap the left and right subtrees of every node, then the resulting tree is called the Mirror Image of a BST.

Now given a sequence of integer keys, you are supposed to tell if it is the preorder traversal sequence of a BST or the mirror image of a BST.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<=1000). Then N 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, first print in a line “YES” if the sequence is the preorder traversal sequence of a BST or the mirror image of a BST, or “NO” if not. Then if the answer is “YES”, print in the next line the postorder traversal sequence of that 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 1:

7
8 6 5 7 10 8 11

Sample Output 1:

YES
5 7 6 8 11 10 8

Sample Input 2:

7
8 10 11 8 6 7 5

Sample Output 2:

YES
11 8 10 7 5 6 8

Sample Input 3:

7
8 6 8 5 10 9 11

Sample Output 3:

NO

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;
struct TreeNode{
int val;
TreeNode *l, *r;
TreeNode(int x) :val(x), l(NULL), r(NULL){};
TreeNode() :val(-1), l(NULL), r(NULL){};
};
TreeNode*dfs(vector<int>&node, int l, int r, bool&buildSuccess)
{//建立正常的BST
if (l>r) return NULL;
else if (l == r)
{
return new TreeNode(node[l]);
}
else
{
TreeNode* root = new TreeNode(node[l]);
int i = l + 1;
while (i <= r&&node[i]<root->val)
{
i++;
}
int j = i;
while (j <= r&&node[j] >= root->val)
{
j++;
}
if (i != r + 1 && j != r + 1)
{//如果i没有达到最终点且j也没有到达最终点,证明数组里面有部分点不满足要求,所以不能构建
buildSuccess = false;
return NULL;
}
root->l = dfs(node, l + 1, i – 1, buildSuccess);
root->r = dfs(node, i, r, buildSuccess);
return root;
}
}

TreeNode*dfsMirror(vector<int>&node, int l, int r, bool&buildSuccess)
{//基本同上
if (l>r) return NULL;
else if (l == r)
{
return new TreeNode(node[l]);
}
else
{
TreeNode* root = new TreeNode(node[l]);
int i = l + 1;
while (i <= r&&node[i] >= root->val)
{
i++;
}
int j = i;
while (j <= r&&node[j]<root->val)
{
j++;
}
if (i != r + 1 && j != r + 1)
{
buildSuccess = false;
return NULL;
}
root->l = dfsMirror(node, l + 1, i – 1, buildSuccess);
root->r = dfsMirror(node, i, r, buildSuccess);
return root;
}
}

void postOrderDFS(TreeNode*root, vector<int>&postOrder)
{
if (root != NULL)
{
postOrderDFS(root->l, postOrder);
postOrderDFS(root->r, postOrder);
postOrder.push_back(root->val);
}
}
/*
7 8 6 5 7 10 8 11

7 8 10 11 8 6 7 5

7 8 6 8 5 10 9 11
*/
int main(void)
{

int nodeSum;
cin >> nodeSum;
vector<int> node(nodeSum);
for (int i = 0; i<nodeSum; i++)
{
scanf("%d", &node[i]);
}
bool buildSuccess = true;
TreeNode*tree = dfs(node, 0, (int)(node.size() – 1), buildSuccess);
if (!buildSuccess)
{
buildSuccess = true;
tree = dfsMirror(node, 0, (int)(node.size() – 1), buildSuccess);
}
if (buildSuccess)
{
cout << "YES" << endl;
vector<int> postOrder(0);
postOrderDFS(tree, postOrder);
for (int i = 0; i<postOrder.size(); i++)
{
cout << postOrder[i];
if (i != postOrder.size() – 1)
cout << " ";
}
cout << endl;
}
else
cout << "NO" << endl;
return 0;
}

[/c]

1042. Shuffling Machine (20)

1.建立一个shuffling数组,把j号卡放在shuffling[j]的位置。

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

Shuffling is a procedure used to randomize a deck of playing cards. Because standard shuffling techniques are seen as weak, and in order to avoid “inside jobs” where employees collaborate with gamblers by performing inadequate shuffles, many casinos employ automatic shuffling machines. Your task is to simulate a shuffling machine.

The machine shuffles a deck of 54 cards according to a given random order and repeats for a given number of times. It is assumed that the initial status of a card deck is in the following order:

S1, S2, …, S13, H1, H2, …, H13, C1, C2, …, C13, D1, D2, …, D13, J1, J2

where “S” stands for “Spade”, “H” for “Heart”, “C” for “Club”, “D” for “Diamond”, and “J” for “Joker”. A given order is a permutation of distinct integers in [1, 54]. If the number at the i-th position is j, it means to move the card from position i to position j. For example, suppose we only have 5 cards: S3, H5, C1, D13 and J2. Given a shuffling order {4, 2, 5, 3, 1}, the result will be: J2, H5, D13, S3, C1. If we are to repeat the shuffling again, the result will be: C1, H5, S3, J2, D13.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer K (<= 20) which is the number of repeat times. Then the next line contains the given order. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the shuffling results in one line. All the cards are separated by a space, and there must be no extra space at the end of the line.

Sample Input:

2
36 52 37 38 3 39 40 53 54 41 11 12 13 42 43 44 2 4 23 24 25 26 27 6 7 8 48 49 50 51 9 10 14 15 16 5 17 18 19 1 20 21 22 28 29 30 31 32 33 34 35 45 46 47

Sample Output:

S7 C11 C10 C12 S1 H7 H8 H9 D8 D9 S11 S12 S13 D10 D11 D12 S3 S4 S6 S10 H1 H2 C13 D2 D3 D4 H6 H3 D13 J1 J2 C1 C2 C3 C4 D1 S5 H5 H11 H12 C6 C7 C8 C9 S2 S8 S9 H10 D5 D6 D7 H4 H13 C5

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;
/*
2
36 52 37 38 3 39 40 53 54 41 11 12 13 42 43 44 2 4 23 24 25 26 27 6 7 8 48 49 50 51 9 10 14 15 16 5 17 18 19 1 20 21 22 28 29 30 31 32 33 34 35 45 46 47
3
36 52 37 38 3 39 40 53 54 41 11 12 13 42 43 44 2 4 23 24 25 26 27 6 7 8 48 49 50 51 9 10 14 15 16 5 17 18 19 1 20 21 22 28 29 30 31 32 33 34 35 45 46 47

1
14 15 16 17 18 19 20 21 22 23 24 25 26 1 2 3 4 5 6 7 8 9 10 11 12 13 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
*/
string int2Card(int a)
{
string ans = "";
int pic = a / 13;
if (pic == 0)ans = "S";
else if (pic == 1) ans = "H";
else if (pic == 2) ans = "C";
else if (pic == 3) ans = "D";
else if (pic == 4) ans = "J";
if (a % 13 >= 9)
{
ans += ‘1’;
char c = (a % 13 – 9) + ‘0’;
ans += c;
}
else
{
char c = a % 13 + ‘1’;
ans += c;
}
return ans;
}
int main(void)
{
//for (int i = 0; i < 54; i++)
//{
// cout << ",\"" << int2Card(i)<<"\"";
//}
int repeatTime;
cin >> repeatTime;
vector<int> shuffling(54);
vector<string> original = { "S1", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9", "S10", "S11", "S12", "S13", "H1", "H2",
"H3", "H4", "H5", "H6", "H7", "H8", "H9", "H10", "H11", "H12", "H13", "C1", "C2", "C3", "C4", "C5","C6","C7","C8","C9","C10","C11","C12","C13","D1","D2","D3","D4","D5","D6","D7","D8","D9","D10","D11","D12","D13","J1","J2"};
vector<string> num(54);
for (int i = 0; i<54; i++)
{
cin >> shuffling[i];
shuffling[i]–;
num[i] = i;// initial the shuffling vector
}

for (int i = 0; i<repeatTime; i++)
{
for (int j = 0; j<54; j++)
{//把j号卡放在shuffling[j]的位置
num[shuffling[j]] = original[j];
}
original = num;
}

for (int i = 0; i<54; i++)
{
cout << original[i];
if (i != 53) cout << " ";
}
return 0;
}

[/c]

1041. Be Unique (20)

1.题目要求求一个数组中,第一个出现的仅出现一次(Unique)的数字。

2.统计各个数字出现的次数。

3.输出第一个出现次数为1的数字。

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

Being unique is so important to people on Mars that even their lottery is designed in a unique way. The rule of winning is simple: one bets on a number chosen from [1, 104]. The first one who bets on a unique number wins. For example, if there are 7 people betting on 5 31 5 88 67 88 17, then the second one who bets on 31 wins.

Input Specification:

Each input file contains one test case. Each case contains a line which begins with a positive integer N (<=105) and then followed by N bets. The numbers are separated by a space.

Output Specification:

For each test case, print the winning number in a line. If there is no winner, print “None” instead.

Sample Input 1:

7 5 31 5 88 67 88 17

Sample Output 1:

31

Sample Input 2:

5 888 666 666 888 888

Sample Output 2:

None

 
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 *frequency = new int[100001];
memset(frequency, 0, 100001 * sizeof(int));
int sum;
cin >> sum;
int *num = new int[sum];
for (int i = 0; i<sum; i++)
{
scanf("%d", &num[i]);
frequency[num[i]]++;
}
for (int i = 0; i<sum; i++)
{
if (frequency[num[i]] == 1)
{
cout << num[i] << endl;
return 0;
}
}
cout << "None" << endl;
return 0;
}

[/c]

1040. Longest Symmetric String (25)

1.求最长回文子字符串。

2.getline输入数据。

3.最好使用manacher方法。

4.暴力方法解决不会超时。

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

Given a string, you are supposed to output the length of the longest symmetric sub-string. For example, given “Is PAT&TAP symmetric?”, the longest symmetric sub-string is “s PAT&TAP s”, hence you must output 11.

Input Specification:

Each input file contains one test case which gives a non-empty string of length no more than 1000.

Output Specification:

For each test case, simply print the maximum length in a line.

Sample Input:

Is PAT&TAP symmetric?

Sample Output:

11

 
暴力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 str;
getline(cin,str);
int maxLen = 0;
for (int i = 0; i<str.size(); i++)
{
int oddLen = 1, evenLen = 0;
for (int j = 1; i – j >= 0 && i + j<str.size(); j++)
{
if (str[i + j] == str[i – j])
oddLen += 2;
else break;
}
for (int j = 0; i – j >= 0 && i + j + 1<str.size(); j++)
{
if (str[i + j + 1] == str[i – j])
evenLen += 2;
else break;
}
maxLen = max(maxLen, max(oddLen, evenLen));
}
cout << maxLen << endl;
return 0;
}

[/c]

1039. Course List for Student (25)

1.题目给出一些课程和选修的学生名单,最后查询学生选修了什么课程。

2.存在超时的危险。

3.根据题意,名字由3个字母和1个数字组成,所以共26*26*26*10=175760种可能,直接开辟内存。

20151116133921234

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

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

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 positive integers: N (<=40000), the number of students who look for their course lists, and K (<=2500), the total number of courses. Then the student name lists are given for the courses (numbered from 1 to K) in the following format: for each course i, first the course index i and the number of registered students Ni (<= 200) are given in a line. Then in the next line, Ni student names are given. A student name consists of 3 capital English letters plus a one-digit number. Finally the last line contains the N names of students who come for a query. All the names and numbers in a line are separated by a space.

Output Specification:

For each test case, print your results in N lines. Each line corresponds to one student, in the following format: first print the student’s name, then the total number of registered courses of that student, and finally the indices of the courses in increasing order. The query results must be printed in the same order as input. All the data in a line must be separated by a space, with no extra space at the end of the line.

Sample Input:

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

Sample Output:

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

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;
/*
ZOE1 2 4 5
ANN0 3 1 2 5
BOB5 5 1 2 3 4 5
JOE4 1 2
JAY9 4 1 2 4 5
FRA8 3 2 4 5
DON2 2 4 5
AMY7 1 5
KAT3 3 2 4 5
LOR6 4 1 2 4 5
NON9 0
*/
int main(void)
{

int querySum, courseSum;
cin >> querySum >> courseSum;
vector<set<int>>stu(175761);//3个字母+1个数字,共26*26*26*10=175760种可能,直接开辟内存
for (int i = 0; i<courseSum; i++)
{
int courseIdx, studentSum;
scanf("%d %d", &courseIdx, &studentSum);
for (int j = 0; j<studentSum; j++)
{
char tmp[5];
scanf("%s", tmp);
int name = (tmp[0]-‘A’)*26*26*10;
name += (tmp[1] – ‘A’) * 26*10 + (tmp[2] – ‘A’) * 10 + tmp[3]-‘0’;
stu[name].insert(courseIdx);
}
}

for (int i = 0; i<querySum; i++)
{
char tmp[5];
scanf("%s", tmp);
int name = (tmp[0] – ‘A’) * 26 * 26 * 10;
name += (tmp[1] – ‘A’) * 26 * 10 + (tmp[2] – ‘A’) * 10 + tmp[3] – ‘0’;
printf("%s %d",tmp,stu[name].size());
for (set<int>::iterator ite = stu[name].begin(); ite != stu[name].end(); ite++)
{
printf(" %d", *ite);
}
cout << endl;
}

return 0;
}
[/c]

1038. Recover the Smallest Number (30)

1.题目是把一些数,通过组合,变成一个最小的数(在这些数的所有组合中最小)

2.使用贪心算法,贪心标准为:

1)如果两个数中,数a是数b的前缀,或者数b是数a的前缀,那么判断字符串相加后a+b与b+a的大小,进行确定前后顺序

2)如果不是上面1)中的两种情况,直接按照string进行大小比较

3.该题目可以通过微小的修改,改为求最大的数。

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

Given a collection of number segments, you are supposed to recover the smallest number from them. For example, given {32, 321, 3214, 0229, 87}, we can recover many numbers such like 32-321-3214-0229-87 or 0229-32-87-321-3214 with respect to different orders of combinations of these segments, and the smallest number is 0229-321-3214-32-87.

Input Specification:

Each input file contains one test case. Each case gives a positive integer N (<=10000) followed by N number segments. Each segment contains a non-negative integer of no more than 8 digits. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the smallest number in one line. Do not output leading zeros.

Sample Input:

5 32 321 3214 0229 87

Sample Output:

22932132143287

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

bool cmp(const string&a,const string&b)
{
//如果a和b,是前缀关系是,要比较a+b与b+a的大小
if(a.size()<b.size()&&a==b.substr(0,a.size()))
return a+b<b+a;
else if(b.size()<a.size() && b==a.substr(0,b.size()))
return a+b<b+a;
else return a<b;
}
/*
5 32 321 3214 0229 87
4 11 122 12 10
4 122 12 10 11
*/

int main(void)
{
int n;
cin>>n;
vector<string> str(n);
for(int i=0;i<n;i++)
{
cin>>str[i];
}
sort(str.begin(), str.end(),cmp);
string ans="";
for(int i=0;i<n;i++)
{
ans+=str[i];
}
int i=0;
while(ans[i] == ‘0’)
{
i++;
}
//注意全为0的状态
if(ans.substr(i)=="") cout<<0<<endl;
else cout<<ans.substr(i)<<endl;
return 0;
}
[/c]

1037. Magic Coupon (25)

1.题目给出一些coupon和product,求最大的value。

2.最大的正数coupon与最大的正数product相乘。

3.最小的负数coupon与最小的负数product相乘(最小的负数即绝对值最大)。

4.其他没有匹配的就不购买了。

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

The magic shop in Mars is offering some magic coupons. Each coupon has an integer N printed on it, meaning that when you use this coupon with a product, you may get N times the value of that product back! What is more, the shop also offers some bonus product for free. However, if you apply a coupon with a positive N to this bonus product, you will have to pay the shop N times the value of the bonus product… but hey, magically, they have some coupons with negative N’s!

For example, given a set of coupons {1 2 4 -1}, and a set of product values {7 6 -2 -3} (in Mars dollars M$) where a negative value corresponds to a bonus product. You can apply coupon 3 (with N being 4) to product 1 (with value M$7) to get M$28 back; coupon 2 to product 2 to get M$12 back; and coupon 4 to product 4 to get M$3 back. On the other hand, if you apply coupon 3 to product 4, you will have to pay M$12 to the shop.

Each coupon and each product may be selected at most once. Your task is to get as much money back as possible.

Input Specification:

Each input file contains one test case. For each case, the first line contains the number of coupons NC, followed by a line with NC coupon integers. Then the next line contains the number of products NP, followed by a line with NP product values. Here 1<= NC, NP <= 105, and it is guaranteed that all the numbers will not exceed 230.

Output Specification:

For each test case, simply print in a line the maximum amount of money you can get back.

Sample Input:

4
1 2 4 -1
4
7 6 -2 -3

Sample Output:

43

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;
bool cmp(const int&a, const int&b)
{
return a > b;
}
int main(void)
{
int n;

vector<int> couponP(0);
vector<int> couponN(0);
vector<int> productP(0);
vector<int> productN(0);
cin >> n;
for (int i = 0; i < n; i++)
{
int a;
scanf("%d", &a);
if (a < 0) couponN.push_back(a);
else couponP.push_back(a);
}

cin >> n;
for (int i = 0; i < n; i++)
{
int a;
scanf("%d", &a);
if (a < 0) productN.push_back(a);
else productP.push_back(a);
}
sort(couponP.begin(), couponP.end(), cmp);
sort(couponN.begin(), couponN.end());
sort(productP.begin(), productP.end(), cmp);
sort(productN.begin(), productN.end());
int sum = 0;
for (int i = 0; i < couponP.size() && i < productP.size(); i++)
sum += couponP[i] * productP[i];
for (int i = 0; i < couponN.size() && i < productN.size(); i++)
sum += couponN[i] * productN[i];
cout << sum << endl;
return 0;
}

[/c]