Codeforces Round #486 (Div. 3) (2018/06/01)
菜鸡第一次打CF,晚上10点和主席跑到综合楼一起肝。一个小时写了前两个签到题然后摸鱼半小时后跑路去吃鸡了。。。凌晨2点多单排五杀第二,一晚上除了没吃到鸡手感还不错。今天学了下map又参考了董先森的代码后把C题过了,先上个博客把前三个题放上去。
A. Diverse Team
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
There are n students in a school class, the rating of the i-th student on Codehorses is ai. You have to form a team consisting of k students (1≤k≤n) such that the ratings of all team members are distinct.
If it is impossible to form a suitable team, print “NO” (without quotes). Otherwise print “YES”, and then print k distinct numbers which should be the indices of students in the team you form. If there are multiple answers, print any of them.
Input
The first line contains two integers n and k (1≤k≤n≤100) — the number of students and the size of the team you have to form.
The second line contains n integers a1,a2,…,an (1≤ai≤100), where ai is the rating of i-th student.
Output
If it is impossible to form a suitable team, print “NO” (without quotes). Otherwise print “YES”, and then print k distinct integers from 1 to n
which should be the indices of students in the team you form. All the ratings of the students in the team should be distinct. You may print the indices in any order. If there are multiple answers, print any of them.
Assume that the students are numbered from 1 to n.
Examples
Input
5 3
15 13 15 15 12
Output
YES
1 2 5
Input
5 4
15 13 15 15 12
Output
NO
Input
4 4
20 10 40 30
Output
YES
1 2 3 4
Note
All possible answers for the first example:
{1 2 5}
{2 3 5}
{2 4 5}
Note that the order does not matter.
题目大意:
给n个学生的分数,问是否能组成一个k个学生的团体,这个团体里每个学生的分数都不相同。
思路:
利用桶排序的思想标记即可。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct student
{
int score;
}a[10100];
int book[10100];
int main()
{
int n,k;
while(scanf("%d %d",&n,&k)!=EOF)
{
int sum=0;
for(int i=1;i<=n;i++)
{
cin>>a[i].score;
if(book[a[i].score]==0)sum++;//统计有几种分数
book[a[i].score]++;
}
if(sum<k)cout<<"NO"<<endl;
else
{
cout<<"YES"<<endl;
int t=1;
for(int i=1;i<=n&&t<=k;i++)
{
if(book[a[i].score]==1){cout<<i<<' ';t++;}//CF对格式的要求并不严格
else if(book[a[i].score]>1)//一种成绩对应多个学生的,用一次后就抹去它
{
cout<<i<<' ';
book[a[i].score]=0;
t++;
}
}
cout<<endl;
}
memset(book,0,sizeof(book));
}
return 0;
}
Substrings Sort
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given n strings. Each string consists of lowercase English letters. Rearrange (reorder) the given strings in such a way that for every string, all strings that are placed before it are its substrings. String a is a substring of string b if it is possible to choose several consecutive letters in b in such a way that they form a. For example, string “for” is contained as a substring in strings “codeforces”, “for” and “therefore”, but is not contained as a substring in strings “four”, “fofo” and “rof”.
Input
The first line contains an integer n (1≤n≤100) — the number of strings.
The next n lines contain the given strings. The number of letters in each string is from 1 to 100
, inclusive. Each string consists of lowercase English letters. Some strings might be equal.
Output
If it is impossible to reorder n given strings in required order, print “NO” (without quotes).
Otherwise print “YES” (without quotes) and n given strings in required order.
Examples
Input
5
a
aba
abacaba
ba
aba
Output
YES
a
ba
aba
aba
abacaba
Input
5
a
abacaba
ba
aba
abab
Output
NO
Input
3
qwerty
qwerty
qwerty
Output
YES
qwerty
qwerty
qwerty
Note
In the second example you cannot reorder the strings because the string “abab” is not a substring of the string “abacaba”.
题目大意:
给n的字符串问是否每个字符串互为子串,如果是,按照长度>字典序的优先级排序输出。
思路:
首先按照题目要求排个序,每次只需要判断前一个字符串是不是后一个字符串的子串就可以了。
一开始我用结构体数组储存,利用strstr(char *c1,char *c2)函数判断是否为子字符串,然后连吃两发RE。之后主席说他用str.find(string s1)函数过的,于是我也换成了字符串,并使用冒泡排序,一发AC了。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
int k;
while(scanf("%d",&k)!=EOF)
{
string s[110];
for(int i=0;i<k;i++)cin>>s[i];
for(int i=0;i<k-1;i++)//冒泡排序
{
for(int j=0;j<k-1;j++)
{
if(s[j].size()>s[j+1].size())
{
string t;
t=s[j];
s[j]=s[j+1];
s[j+1]=t;
}
else if(s[j].size()==s[j+1].size())
{
if(s[j]>s[j+1])
{
string t;
t=s[j];
s[j]=s[j+1];
s[j+1]=t;
}
}
}
}
bool flag=true;
for(int i=0;i<k-1;i++)
{
if(s[i+1].find(s[i])==-1)//前者不是后者的子串
{
flag=false;
break;
}
}
if(flag)//所有字符串满足题意
{
cout<<"YES"<<endl;
for(int i=0;i<k;i++)cout<<s[i]<<endl;
}
else cout<<"NO"<<endl;
}
return 0;
}
C. Equal Sums
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given k sequences of integers. The length of the i-th sequence equals to ni.
You have to choose exactly two sequences i and j (i≠j) such that you can remove exactly one element in each of them in such a way that the sum of the changed sequence i (its length will be equal to ni−1) equals to the sum of the changed sequence j (its length will be equal to nj−1).
Note that it’s required to remove exactly one element in each of the two chosen sequences.
Assume that the sum of the empty (of the length equals 0) sequence is 0.
Input
The first line contains an integer k(2≤k≤2⋅105) — the number of sequences.
Then k pairs of lines follow, each pair containing a sequence.
The first line in the i-th pair contains one integer ni (1≤ni<2⋅105) — the length of the i-th sequence. The second line of the i-th pair contains a sequence of ni integers ai,1,ai,2,…,ai,ni.
The elements of sequences are integer numbers from −104 to 104.
The sum of lengths of all given sequences don’t exceed 2⋅105, i.e. n1+n2+⋯+nk≤2⋅105.
Output
If it is impossible to choose two sequences such that they satisfy given conditions, print “NO” (without quotes). Otherwise in the first line print “YES” (without quotes), in the second line — two integers i, x (1≤i≤k,1≤x≤ni), in the third line — two integers j, y (1≤j≤k,1≤y≤nj). It means that the sum of the elements of the i-th sequence without the element with index x equals to the sum of the elements of the j-th sequence without the element with index y.
Two chosen sequences must be distinct, i.e. i≠j. You can print them in any order.
If there are multiple possible answers, print any of them.
Examples
Input
2
5
2 3 1 3 2
6
1 1 2 2 2 1
Output
YES
2 6
1 2
Input
3
1
5
5
1 1 1 1 1
2
2 3
Output
NO
Input
4
6
2 2 2 2 2 2
5
2 2 2 2 2
3
2 2 2
5
2 2 2 2 2
Output
YES
2 2
4 1
Note
In the first example there are two sequences [2,3,1,3,2] and [1,1,2,2,2,1]. You can remove the second element from the first sequence to get [2,1,3,2] and you can remove the sixth element from the second sequence to get [1,1,2,2,2]. The sums of the both resulting sequences equal to 8, i.e. the sums are equal.
题目大意:
n个整数序列,每个序列含有k个数,是否存在两个整数序列i,j,使得i序列删去它的一个元素x后的和等于j序列删去它的一个元素y的和。是,则输出“YES”,第二行输出i和x,第三行输出j和y。
否则输出“NO”。
思路:
枚举所有可能的答案(即SUMni-x)如果出现相等的且序列编号不相同就说明有这样的两个序列。用map建立一个答案到序列编号与删除元素编号的映射,用pair类来保存序列编号与删除元素编号。
代码如下:
#include<iostream>
#include<map>
using namespace std;
int main()
{
int n;
cin>>n;
map< int,pair<int,int> >ans;
pair<int,int>result;//第一个成员保存序列编号,第二个保存删除元素编号
for(int j=1;j<=n;j++)
{
int k,a[200010]={0},sum=0;
cin>>k;
for(int i=1;i<=k;i++)
{
cin>>a[i];
sum+=a[i];
}
for(int i=1;i<=k;i++)
{
if(!ans.count(sum-a[i]))//答案不存在
{
ans[sum-a[i]]=make_pair(j,i);//放入map中
}
else
{
result=ans[sum-a[i]];//找到的结果赋值给result
if(result.first!=j)//序列编号不同的话
{
cout<<"YES"<<endl;
cout<<j<<" "<<i<<' '<<endl;
cout<<result.first<<' '<<result.second<<endl;
return 0;//找到后程序可以直接结束,不影响结果
}
}
}
}
cout<<"NO"<<endl;
return 0;
}