Codeforces暑期训练周报(7.14~7.20)

A. Police Recruits

time limit per test: 1 second

memory limit per test: 256 megabytes

input: standard input

output: standard output

The police department of your city has just started its journey. Initially, they don’t have any manpower. So, they started hiring new recruits in groups.

Meanwhile, crimes keeps occurring within the city. One member of the police force can investigate only one crime during his/her lifetime.

If there is no police officer free (isn't busy with crime) during the occurrence of a crime, it will go untreated.

Given the chronological order of crime occurrences and recruit hirings, find the number of crimes which will go untreated.

Input

The first line of input will contain an integer n (1 ≤ n ≤ 10^{5}), the number of events. The next line will contain n space-separated integers.

If the integer is -1 then it means a crime has occurred. Otherwise, the integer will be positive, the number of officers recruited together at that time. No more than 10 officers will be recruited at a time.

Output

Print a single integer, the number of crimes which will go untreated.

Examples

input

3
-1 -1 1

output

2

input

8
1 -1 1 -1 -1 1 1 1

output

1

input

11
-1 -1 2 -1 -1 -1 -1 -1 -1 -1 -1

output

8

Note

Lets consider the second example:

  1. Firstly one person is hired.
  2. Then crime appears, the last hired person will investigate this crime.
  3. One more person is hired.
  4. One more crime appears, the last hired person will investigate this crime.
  5. Crime appears. There is no free policeman at the time, so this crime will go untreated.
  6. One more person is hired.
  7. One more person is hired.
  8. One more person is hired.

The answer is one, as one crime (on step 5) will go untreated.

题解:

        这个800分的题就当作是练练手了,做完这个题就开始1100~1300的题目训练了。一个非常简单的用栈模拟的过程,需要注意的是只有当栈顶元素的值变为0的时候才能执行pop()函数,其余的时候要进行top()-1的操作,如果栈为空且当前输入的元素为-1,则untreated的人数+1。

AC代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;

int main()
{
	int n;
	cin>>n;
	int ans=0;
	stack<int> s;
	while (n--){
		int z;
		cin>>z;
		if (z!=-1){
			s.push(z);
		}
		else{
			if (!s.empty()){
				if (s.top()==1){
					s.pop();
				}
				else{
					s.top()--;
				}
			}
			else{
				ans++;
			}
		}
	}
	cout<<ans<<endl;
	return 0;
}

A. Cut Ribbon

time limit per test: 1 second

memory limit per test: 256 megabytes

input: standard input

output: standard output

Polycarpus has a ribbon, its length is n. He wants to cut the ribbon in a way that fulfils the following two conditions:

  • After the cutting each ribbon piece should have length ab or c.
  • After the cutting the number of ribbon pieces should be maximum.

Help Polycarpus and find the number of ribbon pieces after the required cutting.

Input

The first line contains four space-separated integers nab and c (1 ≤ n, a, b, c ≤ 4000) — the length of the original ribbon and the acceptable lengths of the ribbon pieces after the cutting, correspondingly. The numbers ab and c can coincide.

Output

Print a single number — the maximum possible number of ribbon pieces. It is guaranteed that at least one correct ribbon cutting exists.

Examples

input

5 5 3 2

output

2

input

7 5 5 2

output

2

Note

In the first example Polycarpus can cut the ribbon in such way: the first piece has length 2, the second piece has length 3.

In the second example Polycarpus can cut the ribbon in such way: the first piece has length 5, the second piece has length 2.

题解:

        题面很简单,作为一道1300分的题,做法有很多种,主要是暴力和dp两种做法,暴力的话就是枚举,i、j枚举,用c判断,最后取最大值就行;dp的话就是个完全背包,需要注意的是对于dp数组要初始化一下,dp[i]表示容量为i的时候所包含的数量,所以最后的答案是dp[n]。

AC代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;

int main()
{
	int n,a,b,c;
	cin>>n>>a>>b>>c;
	int ans=-1;
	for (int i=0;i*a<=n;i++){
		for (int j=0;i*a+j*b<=n;j++){
			if ((n-i*a-j*b)%c==0){
				ans=max(ans,i+j+(n-i*a-j*b)/c);
			}
		}
	}
	cout<<ans<<endl;
	return 0;
}
#include <bits/stdc++.h>
#define ll long long
using namespace std;

int main()
{
	int n,a[5],dp[4005];
	memset(dp,-0x3f,sizeof(dp));
	cin>>n>>a[1]>>a[2]>>a[3];
	dp[0]=0;
	for (int i=1;i<=3;i++){
		for (int j=a[i];j<=n;j++){
			dp[j]=max(dp[j],dp[j-a[i]]+1);
		}
	}
	cout<<dp[n]<<endl;
	return 0;
}

A. Cheap Travel

time limit per test: 1 second

memory limit per test: 256 megabytes

input: standard input

output: standard output

Ann has recently started commuting by subway. We know that a one ride subway ticket costs a rubles. Besides, Ann found out that she can buy a special ticket for m rides (she can buy it several times). It costs b rubles. Ann did the math; she will need to use subway n times. Help Ann, tell her what is the minimum sum of money she will have to spend to make n rides?

Input

The single line contains four space-separated integers nmab (1 ≤ n, m, a, b ≤ 1000) — the number of rides Ann has planned, the number of rides covered by the m ride ticket, the price of a one ride ticket and the price of an m ride ticket.

Output

Print a single integer — the minimum sum in rubles that Ann will need to spend.

Examples

input

6 2 1 2

output

6

input

5 2 2 3

output

8

Note

In the first sample one of the optimal solutions is: each time buy a one ride ticket. There are other optimal solutions. For example, buy three m ride tickets.

题解:

        这个题的题面很简单,无非就是一个单程票和多程票的问题,一共有三种情况:都买单程票,一共花的钱是n*a;以多程票为主,恰好能满足n趟旅程,即花的钱数为n/m*b+(n%m)*a;全都买多程票,一共花的钱是(n/m)*b或(n/m+1)*b,这三种情况的最小值就是这道题的答案。

AC代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;

int main()
{
	int n,m,a,b;
	cin>>n>>m>>a>>b;
	cout<<min((n%m==0?(n/m):(n/m+1))*b,min(n*a,n/m*b+(n%m)*a))<<endl;
	return 0;
}

B. Interesting drink

time limit per test: 2 seconds

memory limit per test: 256 megabytes

input: standard input

output: standard output

Vasiliy likes to rest after a hard work, so you may often meet him in some bar nearby. As all programmers do, he loves the famous drink "Beecola", which can be bought in n different shops in the city. It's known that the price of one bottle in the shop i is equal to xi coins.

Vasiliy plans to buy his favorite drink for q consecutive days. He knows, that on the i-th day he will be able to spent mi coins. Now, for each of the days he want to know in how many different shops he can buy a bottle of "Beecola".

Input

The first line of the input contains a single integer n (1 ≤ n ≤ 100 000) — the number of shops in the city that sell Vasiliy's favourite drink.

The second line contains n integers xi (1 ≤ xi ≤ 100 000) — prices of the bottles of the drink in the i-th shop.

The third line contains a single integer q (1 ≤ q ≤ 100 000) — the number of days Vasiliy plans to buy the drink.

Then follow q lines each containing one integer mi (1 ≤ mi ≤ 109) — the number of coins Vasiliy can spent on the i-th day.

Output

Print q integers. The i-th of them should be equal to the number of shops where Vasiliy will be able to buy a bottle of the drink on the i-th day.

Example

input

5
3 10 8 6 11
4
1
10
3
11

output

0
4
1
5

Note

On the first day, Vasiliy won't be able to buy a drink in any of the shops.

On the second day, Vasiliy can buy a drink in the shops 1, 2, 3 and 4.

On the third day, Vasiliy can buy a drink only in the shop number 1.

Finally, on the last day Vasiliy can buy a drink in any shop.

题解:

        一道经典的二分模板题,题面很简单,让你输出小于等于某个值的个数,只需要注意while循环别被卡死就行。

        有关二分查找的模板有很多,但是我建议最好自己写一个自己能够理解的模板,了解到每个参数所表达的含义以及每一步希望输出的值和实际输出的值会对二分的题目有很大的帮助。

AC代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+5;
int a[N];
int main()
{
	int n;
	cin>>n;
	for (int i=0;i<n;i++){
		cin>>a[i];
	}
	sort(a,a+n);
	int q;
	cin>>q;
	while (q--){
		int m;
		cin>>m;
		int l=0,r=n-1;
		while (l<=r){
			int mid=(l+r)>>1;
			if (a[mid]>m){
				r=mid-1;
			}
			else{
				l=mid+1;
			}
		}
		cout<<l<<endl;
	}
	return 0;
}

A. Fancy Fence

time limit per test: 2 seconds

memory limit per test: 256 megabytes

input: standard input

output: standard output

Emuskald needs a fence around his farm, but he is too lazy to build it himself. So he purchased a fence-building robot.

He wants the fence to be a regular polygon. The robot builds the fence along a single path, but it can only make fence corners at a single angle a.

Will the robot be able to build the fence Emuskald wants? In other words, is there a regular polygon which angles are equal to a?

Input

The first line of input contains an integer t (0 < t < 180) — the number of tests. Each of the following t lines contains a single integer a (0 < a < 180) — the angle the robot can make corners at measured in degrees.

Output

For each test, output on a single line "YES" (without quotes), if the robot can build a fence Emuskald wants, and "NO" (without quotes), if it is impossible.

Examples

input

3
30
60
90

output

NO
YES
YES

Note

In the first test case, it is impossible to build the fence, since there is no regular polygon with angle 30^{\circ}.

In the second test case, the fence is a regular triangle, and in the last test case — a square.

题解:

        一个比较简单的题目,具体做法就是用外角和的特点,看一下360%外角度数是不是一个整数就可以了。

AC代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;

int main()
{
	int t;
	cin>>t;
	while (t--){
		int n;
		cin>>n;
		cout<<(360%(180-n)==0?"YES":"NO")<<endl;
	}
	return 0;
}

C. K-th Not Divisible by n

time limit per test: 1 second

memory limit per test: 256 megabytes

input: standard input

output: standard output

You are given two positive integers n and k. Print the k-th positive integer that is not divisible by n.

For example, if n=3, and k=7, then all numbers that are not divisible by 3 are: 1,2,4,5,7,8,10,11,13… The 7-th number among them is 10.

Input

The first line contains an integer t (1≤t≤1000) — the number of test cases in the input. Next, t test cases are given, one per line.

Each test case is two positive integers n (2≤n≤10^{9}) and k (1≤k≤10^{9}). 

Output

For each test case print the k-th positive integer that is not divisible by n.

Example

input

6
3 7
4 12
2 1000000000
7 97
1000000000 1000000000
2 1

output

10
15
1999999999
113
1000000001
1

题解:

        这是一道非常好的数学思维题,题面看似不复杂,但做起来的时候不容易对。首先我们能知道的是,每n-1个数为一组,想确定第k个数是啥,就得先到清楚k在第几组中,显然这里就有两种情况:k%(n-1)==0和k%(n-1)!=0,如果等于0,说明这个数是在这个组的最后一个,根据数学公式可以推算出这个数就是n*k/(n-1)-1;如果不等于0,和刚才的思路一样,可以确定这个数在k/(n-1)这个组中,偏移量就是k%(n-1),需要注意的是,一定要先计算组数,再去乘以n,否则答案是错误的。

        当然这个题还有其他的比较简单的做法,在这里就不做过多的叙述。

AC代码: 

#include <bits/stdc++.h>
#define ll long long
using namespace std;

int main()
{
	int t;
	cin>>t;
	while (t--){
		ll n,k;
		cin>>n>>k;
		cout<<(k%(n-1)==0?n*k/(n-1)-1:n*(k/(n-1))+k%(n-1))<<endl;
	}
	return 0;
}

A. Laptops

time limit per test: 1 second

memory limit per test: 256 megabytes

input: standard input

output: standard output

One day Dima and Alex had an argument about the price and quality of laptops. Dima thinks that the more expensive a laptop is, the better it is. Alex disagrees. Alex thinks that there are two laptops, such that the price of the first laptop is less (strictly smaller) than the price of the second laptop but the quality of the first laptop is higher (strictly greater) than the quality of the second laptop.

Please, check the guess of Alex. You are given descriptions of n laptops. Determine whether two described above laptops exist.

Input

The first line contains an integer n (1 ≤ n ≤ 10^{5}) — the number of laptops.

Next n lines contain two integers each, ai and bi (1 ≤ ai, bi ≤ n), where ai is the price of the i-th laptop, and bi is the number that represents the quality of the i-th laptop (the larger the number is, the higher is the quality).

All ai are distinct. All bi are distinct.

Output

If Alex is correct, print "Happy Alex", otherwise print "Poor Alex" (without the quotes).

Examples

input

2
1 2
2 1

output

Happy Alex

题解:

        一道比较简单的结构体排序的题目,题目要求找到一对价格少、质量高的产品即可,那么就可以根据价格升序、质量降序的顺序来排序,只要找到一对就可以,切记不要使用双循环,否则会超时。

AC代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int N=1e5+5;
struct node{
	int q;
	int p;
}nod[N];
bool cmp(node a,node b){
	if (a.p!=b.p){
		return a.q>b.q;
	}
	return a.p<b.p;
}
int main()
{
	int n;
	cin>>n;
	for (int i=0;i<n;i++){
		cin>>nod[i].p>>nod[i].q;
	}
	sort(nod,nod+n,cmp);
	bool f=0;
	for (int i=1;i<n;i++){
		if (nod[i-1].p<nod[i].p&&nod[i-1].q>nod[i].q){
			f=1;
			break;
		}
	}
	cout<<(f?"Happy Alex":"Poor Alex")<<endl;
	return 0;
}

B. Sort the Array

time limit per test: 1 second

memory limit per test: 256 megabytes

input: standard input

output: standard output

Being a programmer, you like arrays a lot. For your birthday, your friends have given you an array a consisting of n distinct integers.

Unfortunately, the size of a is too small. You want a bigger array! Your friends agree to give you a bigger array, but only if you are able to answer the following question correctly: is it possible to sort the array a (in increasing order) by reversing exactly one segment of a? See definitions of segment and reversing in the notes.

Input

The first line of the input contains an integer n (1 ≤ n ≤ 10^{5}) — the size of array a.

The second line contains n distinct space-separated integers: a[1], a[2], ..., a[n] (1 ≤ a[i] ≤ 10^{9}).

Output

Print "yes" or "no" (without quotes), depending on the answer.

If your answer is "yes", then also print two space-separated integers denoting start and end (start must not be greater than end) indices of the segment to be reversed. If there are multiple ways of selecting these indices, print any of them.

Examples

input

3
3 2 1

output

yes
1 3

input

4
2 1 3 4

output

yes
1 2

input

4
3 1 2 4

output

no

input

2
1 2

output

yes
1 1

Note

Sample 1. You can reverse the entire array to get [1, 2, 3], which is sorted.

Sample 3. No segment can be reversed such that the array will be sorted.

Definitions:

A segment [l, r] of array a is the sequence a[l], a[l + 1], ..., a[r].

If you have an array a of size n and you reverse its segment [l, r], the array will become:

a[1], a[2], ..., a[l - 2], a[l - 1], a[r], a[r - 1], ..., a[l + 1], a[l], a[r + 1], a[r + 2], ..., a[n - 1], a[n].

题解:

        这是一道很好的排序题,题意是说让你翻转数组一次,看看能不能使得数组从头到尾是升序的,如果是还要输出左右翻转端点。比较简单和暴力的思路是找到第一个逆序对,然后从这个逆序对的起点开始,找到第一个升序数对,记录下这两个点的坐标,需要注意的是3 2 1这种情况,要对l和r初始化,为了方便计算,我们设数组从1开始存。

        当然这道题还涉及到了两个有关数组的函数:reverse()和is_sorted(),如果用正常的做法可能还需要开一个b数组,用了这两个函数能大大降低我们的代码量,比较的方便。

AC代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int N=1e5+5;
int a[N];
int main()
{
	int n;
	cin>>n;
	for (int i=1;i<=n;i++){
		cin>>a[i];
	}
	int l=1,r=n;
	for (int i=1;i<n;i++){
		if (a[i]>a[i+1]){
			l=i;
			break;
		}
	}
	for (int i=l;i<n;i++){
		if (a[i]<a[i+1]){
			r=i;
			break;
		}
	}
	reverse(a+l,a+r+1);
	if (is_sorted(a+1,a+1+n)){
		cout<<"yes"<<endl;
		cout<<l<<" "<<r<<endl;
	}
	else{
		cout<<"no"<<endl;
	}
	return 0;
}

C. Given Length and Sum of Digits...

time limit per test: 1 second

memory limit per test: 256 megabytes

input: standard input

output: standard output

You have a positive integer m and a non-negative integer s. Your task is to find the smallest and the largest of the numbers that have length m and sum of digits s. The required numbers should be non-negative integers written in the decimal base without leading zeroes.

Input

The single line of the input contains a pair of integers ms (1 ≤ m ≤ 100, 0 ≤ s ≤ 900) — the length and the sum of the digits of the required numbers.

Output

In the output print the pair of the required non-negative integer numbers — first the minimum possible number, then — the maximum possible number. If no numbers satisfying conditions required exist, print the pair of numbers "-1 -1" (without the quotes).

Examples

input

2 15

output

69 96

input

3 0

output

-1 -1

题解:

        这是一道很好的贪心思想的题目,最终题目要求输出的是两个边界的值。我们一个一个分析,最大值就是一堆9后面配0,而最小值需要注意不能有前导0的情况,只能用1代替。

        重点说下最小值,由于是m位数,所有数字之和为s,如果说这个最小值存在,那么就说明他前面只能有1位前导0的出现,所以对第一位单独进行判断即可。

AC代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int N=1e5+5;
void solve(){
	int m,s;
	cin>>m>>s;
	if (s<1&&m>1||s>m*9){
		cout<<"-1 -1"<< endl;
		return;
	}
	string mn="";
	for (int i=m-1,cur=s;i>=0;i--){
		if (max(0,cur-i*9)==0&&i==m-1&&cur!=0){
			mn+="1";
			cur-=1;
			continue;
		}
		mn+=max(0,cur-i*9)+'0';
		cur-=max(0,cur-i*9);
	}
	cout<<mn<<" ";
	string mx="";
	for (int i=m-1,cur=s;i>=0;i--){
		mx+=min(9,cur)+'0';
		cur-=min(9,cur);
	}
	cout<<mx<<endl;
}
int main()
{
	int _;
	//cin>>_;
	_=1; 
	while (_--){
		solve();
	}
	return 0;
}

B. Two Buttons

time limit per test: 2 seconds

memory limit per test: 256 megabytes

input: standard input

output: standard output

Vasya has found a strange device. On the front panel of a device there are: a red button, a blue button and a display showing some positive integer. After clicking the red button, device multiplies the displayed number by two. After clicking the blue button, device subtracts one from the number on the display. If at some point the number stops being positive, the device breaks down. The display can show arbitrarily large numbers. Initially, the display shows number n.

Bob wants to get number m on the display. What minimum number of clicks he has to make in order to achieve this result?

Input

The first and the only line of the input contains two distinct integers n and m (1 ≤ n, m ≤ 10^{4}), separated by a space .

Output

Print a single number — the minimum number of times one needs to push the button required to get the number m out of number n.

Examples

input

4 6

output

2

input

10 1

output

9

Note

In the first example you need to push the blue button once, and then push the red button once.

In the second example, doubling the number is unnecessary, so we need to push the blue button nine times.

题解:

        这是一道非常好的思维题,1400分,用暴力的办法自然能过,而且和下面要说的BFS思想差不多。主要来说说BFS,相当于是对每一个数都做一次判断,因为题目一定是有答案的,所以BFS肯定能找到答案,对于每一个数判断-1和*2的操作是否合法,合法就加入队列之中,同时所对应的步数就+1,直到找到相应的数值m,将它的结果返回,这里当然可以用一个结构体去表示这个数字的两个信息。

AC代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int N=1e4+5;
int ans[N];
bool vis[N];
int bfs(int n,int m){
	queue<int> q;
	q.push(n);
	vis[n]=1;
	ans[n]=0;
	while (!q.empty()){
		int x=q.front();
		q.pop();
		if (x==m){
			return ans[x];
		}
		if (x-1<=N&&x-1>0&&!vis[x-1]){
			vis[x-1]=true;
			q.push(x-1);
			ans[x-1]=ans[x]+1;
		}
		if (x*2<=N&&x*2>0&&!vis[x*2]){
			vis[x*2]=true;
			q.push(x*2);
			ans[x*2]=ans[x]+1;
		}
	}
}
void solve(){
	int n,m;
	cin>>n>>m;
	if (n>=m){
		cout<<n-m<<endl;
	}
	else{
		cout<<bfs(n,m)<<endl;
	}
}
int main()
{
	int _;
	//cin>>_;
	_=1; 
	while (_--){
		solve();
	}
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值