TopCoder SRM 601 div2
转载请注明:http://www.cnblogs.com/dingxiaoxian/ 谢谢~
第一题:(水题)
Problem Statement
It's winter time! Time to eat a lot of mandarins with your friends.
You have several bags with mandarins. You are given an vector <int> bags. For each i, the i-th element of bags represents the number of mandarins in the i-th bag. You are also given an int K.
You want to choose exactly K bags and distribute them among you and your friends. To be as fair as possible, you want to minimize the difference between the chosen bag with most mandarins
and the chosen bag with fewest mandarins.
Return the smallest difference that can be achieved.
Definition
Class: WinterAndMandarins
Method signature: int getNumber(vector
<int> bags, int K)
Limits
Time limit (s):2.000
Memory limit (MB):256
Constraints
bags will contain between 2 and 50 elements, inclusive.
Each element of bags will be between 1 and 1,000,000,000, inclusive.
K will be between 2 and N, inclusive, where N is the number of elements in
bags.
题意&解题思路:
要你在bags数组中选取K个数字,要求选取方法中的最大数字和最小数字的差值在所有选取方法中最小,问你这个最小的差值是多少。
将bags从小到大排序,这样选取连续k个数字必然是比不连续的方法好,然后拿bags[i+K-1]-bags[i]枚举选取连续K个数字的最小值,得到结果。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 using namespace std; 5 class WinterAndMandarins 6 { 7 public: 8 int getNumber(vector <int> bags, int K) 9 { 10 int a[111],len=0; 11 for(vector<int>::size_type i = 0; i != bags.size(); ++i)a[i]=bags[i],len++; 12 sort(a,a+len); 13 int ans=1000000001; 14 for(int i=0; i<=len-K; i++) 15 ans=min(ans,a[i+K-1]-a[i]); 16 return ans; 17 } 18 };
第二题:(水题)
Problem Statement
It's winter time! You have some candies arranged in a row and now you want to
choose some of them and give them to your friend.
You are given a vector <int> type. Each candy has a type, which is some positive integer. For each i, type[i] represents the type of i-th candy. You want to choose some non-empty subset of
candies with the following property: if the number of candies you choose is K, their types must be precisely all the numbers from 1 to K, inclusive. Return the number of different ways to do that.
(Two ways are considered different if
there exists some candy that is chosen in only one of them.)
Definition
Class: WinterAndCandies
Method signature: int getNumber(vector <int> type)
Limits
Time limit (s):2.000
Memory limit (MB):256
Constraints
type will contain between 1 and 50 elements, inclusive.
Each element of type will be between 1 and 50, inclusive.
题意&解题思路:
type[i]表示第i个元素的种类,现在要你选取某几个元素,要求是选取的i个元素刚好分别属于1-i的种类(每种一个),问这样的选取方法共有多少种。
先将每种类型的元素数量统计出来(id数组),然后从1开始,选取i个元素的方法数量是选取i-1种元素的方法数量乘以第k种元素的数量。ans[i]=id[i]*ans[i-1];
再将选取1-n个元素的方法数量累加得到结果。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 #include<string.h> 5 using namespace std; 6 class WinterAndCandies 7 { 8 public: 9 int getNumber(vector <int> type) 10 { 11 int id[55],ans[55]; 12 memset(ans,0,sizeof(ans)); 13 memset(id,0,sizeof(id)); 14 for(vector<string>::size_type i = 0; i != type.size(); ++i)id[type[i]]++; 15 for(int i=1; i<55; i++) 16 if(id[i]==0)break; 17 else if(i==1)ans[i]=id[i]; 18 else ans[i]=id[i]*ans[i-1]; 19 int sum=0; 20 for(int i=1; i<55; i++)sum+=ans[i]; 21 return sum; 22 } 23 };
第三题:
Problem Statement
It's winter time! Time to play some games.
Four reindeers are playing the following game. The first three of them choose three non-empty strings: A, B, and C. (The strings are not necessarily distinct.) Then, the fourth one
(and it happens to
be the youngest one) finds a string S that satisfies the following conditions:
S is a subsequence of A. (I.e., either S equals A, or S can be obtained from A
by removing some of its characters.)
S is a subsequence of B.
C is a (contiguous) substring of S.
There is no string longer than S that satisfies the previous three conditions.
You are given three vector <string>s allA, allB and allC. Concatenate all elements of allA, allB and allC to obtain strings A, B and C, respectively.
Return the length of the string S. If there
is no such string, return 0.
Definition
Class: WinterAndReindeers
Method signature: int getNumber(vector <string> allA,
vector <string> allB, vector <string> allC)
Limits
Time limit (s):2.000
Memory limit (MB):256
Constraints
allA, allB and allC will each contain between 1 and 50 elements, inclusive.
Each element of allA, allB and allC will contain between 1 and 50 characters,
inclusive.
Each element of allA, allB and allC will consist only of uppercase English
letters ('A'-'Z').
题意&解题思路:
学渣被这题坑了好多次= =。至今不能理解为什么它要以vector的形式给一连串string,而不是直接给三个string a,b,c;
题目要求就是让你弄出一个字符串S,它能保证是A的子串,B的子串,同时C是S的一个连续子串。
我的方法就是先在A和B中枚举找到存在子串C时子串的位置,记录下子串的开头下标和结尾下标,然后对C之外的地方找最长公共子序列。
如
A="ABCDEF",B="CVABCEGF",C="BCE"
这时A中存在子串C,此时子串的开始下标为1,结束下标为4;
这时B中存在子串C,此时子串的开始下标为3,结束下标为5;
我们在C之外的地方A(0-0)和B(0-2)的最长公共子序列长度S1和A(5-5)和B(6-7)的最长公共子序列长度S2以及C的长度lC三者之和就是这种拆分方法所能得到S最长的长度了。
遍历每种组合求最大值。
但一开始想的是四重循环找位置,然后写个函数寻找最长公共子序列。太暴力了,TLE了。
然后不用函数找,先用dp2存下所有的以i,j结尾时最长公共子序列的长度dp2[i][j],最后两组超时了= =;
最后删除两重循环改用pair记录每种位置,然后再两重循环把位置组合以便利所有答案,终于过了。//现在想想,还是比赛的时候太天真,没有细致考虑复杂度。函数里的复杂度没考虑进去,不应当。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 #include <vector> 6 #include <queue> 7 #include <set> 8 #include <map> 9 #include <string> 10 #include <math.h> 11 #include <stdlib.h> 12 using namespace std; 13 class WinterAndReindeers 14 { 15 public: 16 int dp[55*55][55*55],dp2[55*55][55*55]; 17 bool dfs(string a,string c,int nowa,int &x) 18 { 19 int cnt=0,lc=c.length(),la=a.length(); 20 for(int i=nowa; i<la; i++) 21 if(a[i]==c[cnt]) 22 { 23 cnt++; 24 if(cnt==lc) 25 { 26 x=i+1; 27 return true; 28 } 29 } 30 return false; 31 } 32 int solve(string a,string b,string c) 33 { 34 int ans=0,la=a.length(),lb=b.length(),lc=c.length(),x1,x2,y1,y2; 35 memset(dp2,0,sizeof(dp2)); 36 for(int i=1; i<=la; i++) 37 for(int j=1; j<=lb; j++) 38 if(a[i-1]==b[j-1])dp2[i][j]=dp2[i-1][j-1]+1; 39 else if(dp2[i][j-1]>=dp2[i-1][j])dp2[i][j] = dp2[i][j-1]; 40 else dp2[i][j] = dp2[i-1][j]; 41 memset(dp,0,sizeof(dp)); 42 for(int i=la-1; i>=0; i--) 43 for(int j=lb-1; j>=0; j--) 44 if(a[i]==b[j])dp[i][j]=dp[i+1][j+1]+1; 45 else if(dp[i][j+1]>=dp[i+1][j])dp[i][j]=dp[i][j+1]; 46 else dp[i][j]=dp[i+1][j]; 47 vector<pair<int,int> > p[2]; 48 for(int i=0,x=0; i<la; i++)if(a[i]==c[0]&&dfs(a,c,i,x))p[0].push_back(make_pair(i,x)); 49 for(int j=0,y=0; j<lb; j++)if(b[j]==c[0]&&dfs(b,c,j,y))p[1].push_back(make_pair(j,y)); 50 for(vector<string>::size_type t1=0; t1!=p[0].size(); t1++) 51 for(vector<string>::size_type t2=0; t2!=p[1].size(); t2++) 52 x1=p[0][t1].first,y1=p[1][t2].first,x2=p[0][t1].second,y2=p[1][t2].second,ans=max(ans,(int)(lc+dp2[x1][x2]+dp[y1][y2])); 53 return ans; 54 } 55 int getNumber(vector <string> allA, vector <string> allB, vector <string> allC) 56 { 57 string A,B,C; 58 for(vector<string>::size_type i=0; i!=allA.size(); i++)A+=allA[i]; 59 for(vector<string>::size_type j=0; j!=allB.size(); j++)B+=allB[j]; 60 for(vector<string>::size_type k=0; k!=allC.size(); k++)C+=allC[k]; 61 return solve(A,B,C); 62 } 63 };