ATCoder Beginner Contest 281

ATCoder Beginner Contest 281

A - Count Down

Problem Statement

Print all non-negative integers less than or equal to N N N in descending order.

Constraints

  • 1 ≤ N ≤ 100 1 \leq N \leq 100 1N100
  • N N N is an integer.

Input

The input is given from Standard Input in the following format:

N N N

Output

Print X X X lines, where X X X is the number of non-negative integers less than or equal to N N N.
For each i = 1 , 2 , … , X i=1, 2, \ldots, X i=1,2,,X, the i i i-th line should contain the i i i-th greatest non-negative integer less than or equal to N N N.


Sample Input 1
3
Sample Output 1
3
2
1
0

We have four non-negative integers less than or equal to 3 3 3, which are 0 0 0, 1 1 1, 2 2 2, and 3 3 3.
To print them in descending order, print 3 3 3 in the first line, 2 2 2 in the second, 1 1 1 in the third, and 0 0 0 in the fourth.


Sample Input 2
22
Sample Output 2
22
21
20
19
18
17
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0

题目大意:

给出一个正整数 N N N,要求输出 N N N 0 0 0

分析:

直接输出。

#include<bits/stdc++.h>
using namespace std;
int n;
int main(){
	cin>>n;
	for(int i=n;i>=0;--i)
		cout<<i<<endl;
	return 0;
}

B - Sandwich Number

Problem Statement

You are given a string S S S consisting of uppercase English letters and digits. Determine whether S S S satisfies the following condition.

  • S S S is a concatenation of the following characters and string in the order listed.
    • An uppercase English letter
    • A string of length 6 6 6 that is a decimal representation of an integer between 100000 100000 100000 and 999999 999999 999999, inclusive
    • An uppercase English letter

Constraints

  • S S S consists of uppercase English letters and digits.
  • The length of S S S is between 1 1 1 and 10 10 10, inclusive.

Input

The input is given from Standard Input in the following format:

S S S

Output

If S S S satisfies the condition in the problem statement, print Yes; otherwise, print No.


Sample Input 1
Q142857Z
Sample Output 1
Yes

SS is a concatenation of Q, 142857, and Z in this order.
Q and Z are uppercase English letters, and 142857 is a string of length 6 6 6 that is a decimal representation of an integer between 100000 100000 100000 and 999999 999999 999999, so S S S satisfies the condition.


Sample Input 2
AB912278C
Sample Output 2
No

AB is not an uppercase English letter, so S S S does not satisfy the condition.


Sample Input 3
X900000
Sample Output 3
No

The last character of S S S is not an uppercase English letter, so S S S does not satisfy the condition.


Sample Input 4
K012345K
Sample Output 4
No

012345 is not a string of length 6 6 6 that is a decimal representation of an integer between 100000 100000 100000 and 999999 999999 999999, so S S S does not satisfy the condition.

题目大意:

给定一个字符串,需满足下列条件:

  • 字符串长度为 8 8 8
  • 首位是大写字母。
  • 2 ∼ 7 2 \sim 7 27 位可以组成一个六位数。(注意六位数首位不能为 0 0 0
  • 末位是大写字母。

判断给定的字符串是否满足要求。

分析:

判断。(下面的有点丑)

#include<bits/stdc++.h>
using namespace std;
string s;
bool check(char ch){
	return 'A'<=ch&&ch<='Z';//判断是否是大写字母
}
int main(){
	cin>>s;
	if(s.length()!=8)
		cout<<"No"<<endl;
	else{
		if(check(s[0])){//首位为大写字母
			if(check(s[1]))//第二位为数字
				cout<<"No"<<endl;
			else{
				if(s[1]=='0')//第二位不为0
					cout<<"No"<<endl;
				else{
					if(check(s[7])){//末位为大写字母
						bool flag=false;
						for(int i=1;i<=6;++i)
							if(check(s[i]))
								flag=true;
						if(flag)//中六位为数字
							cout<<"No"<<endl;
						else
							cout<<"Yes"<<endl;
					}else
						cout<<"No"<<endl;
				}
			}
		}else
			cout<<"No"<<endl;
	}
	return 0;
}

C - Circular Playlist

Problem Statement

We have a playlist with NN songs numbered 1 , … , N 1, \dots, N 1,,N.
Song i i i lasts A i A_i Ai seconds.

When the playlist is played, song 1 1 1, song 2 2 2, … … \ldots… ……, and song N N N play in this order. When song N N N ends, the playlist repeats itself, starting from song 1 1 1 again. While a song is playing, the next song does not play; when a song ends, the next song starts immediately.

At exactly T T T seconds after the playlist starts playing, which song is playing? Also, how many seconds have passed since the start of that song?
There is no input where the playlist changes songs at exactly T T T seconds after it starts playing.

Constraints

  • 1 ≤ N ≤ 1 0 5 1 \leq N \leq 10^5 1N105
  • 1 ≤ T ≤ 1 0 18 1 \leq T \leq 10^{18} 1T1018
  • 1 ≤ A i ≤ 1 0 9 1 \leq A_i \leq 10^9 1Ai109
  • The playlist does not change songs at exactly T T T seconds after it starts playing.
  • All values in the input are integers.

Input

The input is given from Standard Input in the following format:

N N N T T T

A 1 A_1 A1 … \ldots A N A_N AN

Output

Print an integer representing the song that is playing at exactly T T T seconds after the playlist starts playing, and an integer representing the number of seconds that have passed since the start of that song, separated by a space.


Sample Input 1
3 600
180 240 120
Sample Output 1
1 60

When the playlist is played, the following happens. (Assume that it starts playing at time 0 0 0.)

  • From time 0 0 0 to time 180 180 180, song 1 1 1 plays.
  • From time 180 180 180 to time 420 420 420, song 2 2 2 plays.
  • From time 420 420 420 to time 540 540 540, song 3 3 3 plays.
  • From time 540 540 540 to time 720 720 720, song 1 1 1 plays.
  • From time 720 720 720 to time 960 960 960, song 2 2 2 plays.
  • ⋮ \qquad\vdots

At time 600 600 600, song 1 1 1 is playing, and 60 60 60 seconds have passed since the start of that song.


Sample Input 2
3 281
94 94 94
Sample Output 2
3 93

Sample Input 3
10 5678912340
1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000
Sample Output 3
6 678912340

题目大意:

给定 n n n 首歌曲,每首歌的时间是 a i a_i ai 秒。从 a 1 a_1 a1 开始循环播放( a 1 → ⋯ → a n → a 1 → ⋯ a_1 \to \cdots \to a_n \to a_1 \to \cdots a1ana1)。

T T T 秒后正在播哪首曲子,同时已经播了多长时间。

分析:

取模。

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100010
#define ll long long
int n;
ll t,a[MAXN];
int main(){
	cin>>n>>t;
	for(int i=1;i<=n;++i)
		cin>>a[i],a[i]+=a[i-1];
	t%=a[n];
	for(int i=1;i<=n;++i)
		if(t<=a[i]){
			cout<<i<<" "<<t-a[i-1]<<endl;
			break;
		}
	return 0;
}

D - Max Multiple

Problem Statement

You are given a sequence of non-negative integers A = ( a 1 , a 2 , … , a N ) A=(a_1,a_2,\ldots,a_N) A=(a1,a2,,aN).

Let S S S be the set of non-negative integers that can be the sum of K K K terms in A A A (with distinct indices).

Find the greatest multiple of D D D in S S S. If there is no multiple of D D D in S S S, print -1 instead.

Constraints

  • 1 ≤ K ≤ N ≤ 100 1 \leq K \leq N \leq 100 1KN100
  • 1 ≤ D ≤ 100 1 \leq D \leq 100 1D100
  • 0 ≤ a i ≤ 1 0 9 0 \leq a_i \leq 10^9 0ai109
  • All values in the input are integers.

Input

The input is given from Standard Input in the following format:

N N N K K K D D D

a 1 a_1 a1 … \ldots a N a_N aN

Output

Print the answer.


Sample Input 1
4 2 2
1 2 3 4
Sample Output 1
6

Here are all the ways to choose two terms in A A A.

  • Choose a 1 a_1 a1 and a 2 a_2 a2, whose sum is 1 + 2 = 3 1+2=3 1+2=3.
  • Choose a 1 a_1 a1 and a 3 a_3 a3, whose sum is 1 + 3 = 4 1+3=4 1+3=4.
  • Choose a 1 a_1 a1 and a 4 a_4 a4, whose sum is 1 + 4 = 5 1+4=5 1+4=5.
  • Choose a 2 a_2 a2 and a 3 a_3 a3, whose sum is 2 + 3 = 5 2+3=5 2+3=5.
  • Choose a 2 a_2 a2 and a 4 a_4 a4, whose sum is 2 + 4 = 6 2+4=6 2+4=6.
  • Choose a 3 a_3 a3 and a 4 a_4 a4, whose sum is 3 + 4 = 7 3+4=7 3+4=7.

Thus, we have S = { 3 , 4 , 5 , 6 , 7 } S=\{3,4,5,6,7\} S={3,4,5,6,7}. The greatest multiple of 2 2 2 in S S S is 6 6 6, so you should print 6 6 6.


Sample Input 2
3 1 2
1 3 5
Sample Output 2
-1

In this example, we have S = { 1 , 3 , 5 } S=\{1,3,5\} S={1,3,5}. Nothing in S S S is a multiple of 2 2 2, so you should print -1.

题目大意:

给定 n n n 个数。现在可以从中选 k k k 个数,需满足他们的和为 d d d 的倍数。求最大和值。

分析:

日常前三红题 第四黄题。

动规,参数一为 i d id id,参数二为“当前已经选择了多少个数”​(不包括自己),参数三为“所需要的余数”(详见代码)。

二进制枚举:

14 / 29 14/29 14/29

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int k,n,d;
ll a[105];
int main(){
	cin>>n>>k>>d;
	for(int i=1;i<=n;++i)
		cin>>a[i];
	ll ans=-1;
	bool vh[105];
	memset(vh,false,sizeof(vh));
	for(int i=n-k+1;i<=n;++i)
		vh[i]=true;
	do{
		ll x=0;
		for(int i=1;i<=n;++i)
			if(vh[i])
				x+=a[i];
		if(x%d==0)
			ans=max(ans,x);
	}while(next_permutation(vh+1,vh+1+n));
	cout<<ans<<endl;
	return 0;
}
动规:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,k,d,a[105];
ll dp[105][105][105];
ll dfs(int id,int al,int re){
	if(al==k){//已经选完了
		if(re==0)//如果正好找到结束点re==0的,则表明结果是d的倍数
			return 0;
		return -1;//返回-1表示“此路不通”
	}if(id+k-al-1>n)//超出范围了,则返回-1
		return -1;
	if(dp[id][al][re]!=-2)
		return dp[id][al][re];
	ll v1=dfs(id+1,al,re);//如果不选自己
	ll v2=dfs(id+1,al+1,((re-a[id])%d+d)%d);//选了自己,则下一个数所需要的余数为((re-a[id])%d+d)%d
	if(v1==-1){//不选自己“此路不通”
		if(v2==-1)//选了自己还是“此路不通”
			return dp[id][al][re]=-1;//整个“此路不通”
		else//选了自己“可行”
			return dp[id][al][re]=v2+a[id];//记得加上自己a[id]
	}else{//不选自己“可行”
		if(v2==-1)//选了自己"此路不通"
			return dp[id][al][re]=v1;//返回不选自己的v1
		else//选了自己也是"可行"
			return dp[id][al][re]=max(v1,v2+a[id]);//返回两者较大的一个
	}
}
int main(){
	cin>>n>>k>>d;
	for(int i=1;i<=n;++i)
		cin>>a[i];
	for(int i=1;i<=n;++i)
	for(int j=0;j<=k;++j)
	for(int l=0;l<d;++l)
		dp[i][j][l]=-2;//初始化为-2
	cout<<dfs(1,0,0)<<endl;//输出
	return 0;
}

E - Least Elements

Problem Statement

You are given an integer sequence A = ( A 1 , … , A N ) A = (A_1, \dots, A_N) A=(A1,,AN) of length N N N, and integers M M M and K K K.
For each i = 1 , … , N − M + 1 i = 1, \dots, N - M + 1 i=1,,NM+1, solve the following independent problem.

Find the sum of the first K K K values in the sorted list of the M M M integers A i , A i + 1 , … , A i + M − 1 A_i, A_{i + 1}, \dots, A_{i + M - 1} Ai,Ai+1,,Ai+M1 in ascending order.

Constraints

  • 1 ≤ K ≤ M ≤ N ≤ 2 × 1 0 5 1 \leq K \leq M \leq N \leq 2 \times 10^5 1KMN2×105
  • 1 ≤ A i ≤ 1 0 9 1 \leq A_i \leq 10^9 1Ai109
  • All values in the input are integers.

Input

The input is given from Standard Input in the following format:

N N N M M M K K K

A 1 A_1 A1 A 2 A_2 A2 … \ldots A N A_N AN

Output

Let a n s w e r k \mathrm{answer}_k answerk be the answer to the problem for i = k i = k i=k, and print them in the following format:

a n s w e r 1 \mathrm{answer}_1 answer1 a n s w e r 2 \mathrm{answer}_2 answer2 … \ldots a n s w e r N − M + 1 \mathrm{answer}_{N-M+1} answerNM+1


Sample Input 1
6 4 3
3 1 4 1 5 9
Sample Output 1
5 6 10
  • For i = 1 i = 1 i=1, sorting A i , A i + 1 , A i + 2 , A i + 3 A_i, A_{i+1}, A_{i+2}, A_{i+3} Ai,Ai+1,Ai+2,Ai+3 in ascending order yields 1 , 1 , 3 , 4 1, 1, 3, 4 1,1,3,4, where the sum of the first three values is 5 5 5.
  • For i = 2 i = 2 i=2, sorting A i , A i + 1 , A i + 2 , A i + 3 A_i, A_{i+1}, A_{i+2}, A_{i+3} Ai,Ai+1,Ai+2,Ai+3 in ascending order yields 1 , 1 , 4 , 5 1, 1, 4, 5 1,1,4,5, where the sum of the first three values is 6 6 6.
  • For i = 3 i = 3 i=3, sorting A i , A i + 1 , A i + 2 , A i + 3 A_i, A_{i+1}, A_{i+2}, A_{i+3} Ai,Ai+1,Ai+2,Ai+3 in ascending order yields 1 , 4 , 5 , 9 1, 4, 5, 9 1,4,5,9, where the sum of the first three values is 10 10 10.

Sample Input 2
10 6 3
12 2 17 11 19 8 4 3 6 20
Sample Output 2
21 14 15 13 13

题目大意:

给定一个序列 A A A,对于每个 1 ≤ i ≤ N − M + 1 1 \le i \le N - M + 1 1iNM+1,将 A i A i + 1 ⋯ A i + M − 1 A_i A_{i + 1} \cdots A_{i + M - 1} AiAi+1Ai+M1 从小到大排序后(不影响原序列),求出 a n s i = ∑ i = 1 K \mathrm{ans}_i = \sum\limits_{i=1}^{K} ansi=i=1K

分析:

nth硬核找

O ( n 2 l o g n ) , 8 / 21 O(n^2logn),8/21 O(n2logn),8/21

#include<bits/stdc++.h>
using namespace std;
#define MAXN 200010
#define ll long long
int n,m,k,a[MAXN];
ll ans;
int main(){
	cin>>n>>m>>k;
	for(int i=1;i<=n;++i)
		cin>>a[i];
	int t[m+1];
	for(int i=1;i<=n-m+1;++i){
		ans=0;
		for(int j=i;j<=i+m-1;++j)
			t[j-i+1]=a[j];
		nth_element(t+1,t+k,t+m+1);
		for(int j=1;j<=k;++j)
			ans+=t[j];
		cout<<ans<<" ";
	}cout<<endl;
	return 0;
}
multiset硬核找

11 / 21 11/21 11/21

#include<bits/stdc++.h>
using namespace std;
#define MAXN 200010
#define ll long long
int n,m,k,a[MAXN];
multiset<int>seq;
int main(){
	cin>>n>>m>>k;
	for(int i=1;i<=n;++i)
		cin>>a[i];
	for(int i=0;i<m;++i)
		seq.insert(a[i]);
	for(int i=1;i<=n-m+1;++i){
		seq.erase(seq.find(a[i-1]));
		seq.insert(a[i+m-1]);
		ll ans=0;
		int j=0;
		multiset<int>::iterator it=seq.begin();
		while(++j<=k){
			ans+=*it;
			++it;
		}cout<<ans<<" ";
	}cout<<endl;
	return 0;
}
双multiset不清空查找

一开始试图用一个整体 ( i ∼ i + m − 1 ) (i\sim i+m-1) (ii+m1)一个局部 ( i ∼ i + k − 1 ) (i\sim i+k-1) (ii+k1)的集合,但是就是做不出来(渣)。

后来用两个局部的集合很快就做出来了 (0.5s就做出来了,你说效率高不高)

#include<bits/stdc++.h>
using namespace std;
#define MAXN 200010
#define ll long long
int k,m,n,a[MAXN];
ll ans=0;
multiset<int>Le,El;//其实是从题目"Least Elements"中截下来的,看上去舒服(咳)
int main(){
	cin>>n>>m>>k;
	for(int i=1;i<=n;++i)
		cin>>a[i];
	int b[m+1];
	for(int i=1;i<=m;++i)
		b[i]=a[i];
	sort(b+1,b+1+m);
	for(int i=1;i<=k;++i)//先把最先的做出来
		Le.insert(b[i]),ans+=b[i];//Le集合表示(i~(i+k-1))的数
	for(int i=k+1;i<=m;++i)//先把最先的做出来
		El.insert(b[i]);//El集合表示(i~(i+m-1))中除去Le的部分数
	cout<<ans<<" ";
	for(int i=2;i<=n-m+1;++i){//a[i-1]是整个里面需要删除的,a[i+m-1]是需要添加的
		if(El.find(a[i-1])!=El.end())//如果要删除的数在“非”部分能找到,则删El的
			El.erase(El.find(a[i-1]));
		else//如果找不到,则在“ans范围”内,删除Le的
			Le.erase(Le.find(a[i-1])),ans-=a[i-1];//tips:"对Le增减时,ans也要同时增减"
		if(Le.size()==0||a[i+m-1]>*Le.rbegin())//如果ans部分没数||要插入的数比ans部分的每个数都大,插入El中
			El.insert(a[i+m-1]);
		else//如果a[i+m-1]不大于ans中的最大数,则插入Le中
			Le.insert(a[i+m-1]),ans+=a[i+m-1];
		if(Le.size()>k){//如果Le超量,则尾巴放到El中
			int x=*Le.rbegin();
			Le.erase(--Le.end());
			El.insert(x);
			ans-=x;
		}if(Le.size()<k){//如果Le缺了,则El的头放到Le中
			int x=*El.begin();
			El.erase(El.begin());
			Le.insert(x);
			ans+=x;
		}cout<<ans<<" ";
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值