[CF] Educational Codeforces Round 23

第一次打CF 有点小激动 传送

这场比赛是2017.6.15 晚上11.05开始的

本人巨弱。。 瞬间被秒杀只A了第一个水题 第二题迷迷糊糊就错了花了好久都没改出来 以为自己方法错了果断放弃 就睡了。。

只好在第二天早上重新请教大犇 重新做一遍了

(某大神:这些题很简单啊 我大概做个5。6题没问题吧) QwQ

A. Treasure Hunt
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Captain Bill the Hummingbird and his crew recieved an interesting challenge offer. Some stranger gave them a map, potion of teleportation and said that only this potion might help them to reach the treasure.

Bottle with potion has two values x and y written on it. These values define four moves which can be performed using the potion:

Map shows that the position of Captain Bill the Hummingbird is (x1, y1) and the position of the treasure is (x2, y2).

You task is to tell Captain Bill the Hummingbird whether he should accept this challenge or decline. If it is possible for Captain to reach the treasure using the potion then output "YES", otherwise "NO" (without quotes).

The potion can be used infinite amount of times.

Input

The first line contains four integer numbers x1, y1, x2, y2 ( - 105 ≤ x1, y1, x2, y2 ≤ 105) — positions of Captain Bill the Hummingbird and treasure respectively.

The second line contains two integer numbers x, y (1 ≤ x, y ≤ 105) — values on the potion bottle.

Output

Print "YES" if it is possible for Captain to reach the treasure using the potion, otherwise print "NO" (without quotes).

Examples
input
0 0 0 6
2 3
output
YES
input
1 1 3 6
1 5
output
NO

题解

明明此题巨水 我还差点写了bfd广搜。后来发现根本不用 

直接用(x2-x1)/a  (y2-y1)/b 判断(a-b)%2就行..因为x2是由x+n*a得来的 y2也是

于是便3分钟打了正解。。但第一遍交还交错了语言 。。。

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define N 10005
using namespace std;
int main(){
	int x1,x2,y1,y2;
	scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
	int a,b;
	scanf("%d%d",&a,&b);
	if((x2-x1)%a!=0||(y2-y1)%b!=0){
		printf("NO");
		return 0;
	}
	int n1=(x2-x1)/a;
	int n2=(y2-y1)/b;
	if((n1-n2)%2==0)
		printf("YES");
	else 
		printf("NO");
	return 0;
}
B. Makes And The Product
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

After returning from the army Makes received a gift — an array a consisting of n positive integer numbers. He hadn't been solving problems for a long time, so he became interested to answer a particular question: how many triples of indices (i,  j,  k) (i < j < k), such that ai·aj·ak is minimum possible, are there in the array? Help him with it!

Input

The first line of input contains a positive integer number n (3 ≤ n ≤ 105) — the number of elements in array a. The second line containsn positive integer numbers ai (1 ≤ ai ≤ 109) — the elements of a given array.

Output

Print one number — the quantity of triples (i,  j,  k) such that i,  j and k are pairwise distinct and ai·aj·ak is minimum possible.

Examples
input
4
1 1 1 1
output
4
input
5
1 3 2 3 4
output
2
input
6
1 3 3 1 3 2
output
1
Note

In the first example Makes always chooses three ones out of four, and the number of ways to choose them is 4.

In the second example a triple of numbers (1, 2, 3) is chosen (numbers, not indices). Since there are two ways to choose an element 3, then the answer is 2.

In the third example a triple of numbers (1, 1, 2) is chosen, and there's only one way to choose indices.

题解

找出最小的三个数 这三个数肯的是要选的

设为n1,n2,n3 统计n1,n2,n3的个数

然后分类讨论 n1n2n3是否相等 然后求组合数C(2,x)或者C(3,x)即可

我虽然想到了 但是代码错了一堆 10^18 用long long就行了啊。。。

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define ll long long
#define N 100005
using namespace std;
int n;
int a[N];
ll C(ll x,ll y){
	if(y==3)return (x-2)*(x-1)*x/6;
	else return (x-1)*x/2;
}
int main(){  
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    sort(a+1,a+1+n);
    int n1=a[1],n2=a[2],n3=a[3];
    if(n1==n2&&n2==n3){
    	int cnt=0;
    	for(int i=1;i<=n;i++)cnt+=a[i]==n1;
    	printf("%lld\n",C(cnt,3ll));
	}
	else if(n1==n2){
		int cnt1=0,cnt2=0;
		for(int i=1;i<=n;i++){
			cnt1+=a[i]==n1;
			cnt2+=a[i]==n3;
		}
		printf("%lld\n",1ll*C(cnt1,2)*cnt2);
	}
	else if(n2==n3){
		int cnt1=0,cnt2=0;
		for(int i=1;i<=n;i++){
			cnt1+=a[i]==n1;
			cnt2+=a[i]==n3;
		}
		printf("%lld\n",1ll*C(cnt2,2)*cnt1);	
	}
	else{
		int cnt1=0,cnt2=0,cnt3=0;
		for(int i=1;i<=n;i++){
			cnt1+=a[i]==n1;
			cnt2+=a[i]==n2;
			cnt3+=a[i]==n3;
		}
		printf("%lld\n",1ll*cnt1*cnt2*cnt3);
	}
    return 0;  
}  


C. Really Big Numbers
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Ivan likes to learn different things about numbers, but he is especially interested in really big numbers. Ivan thinks that a positive integer number x is really big if the difference between x and the sum of its digits (in decimal representation) is not less than s. To prove that these numbers may have different special properties, he wants to know how rare (or not rare) they are — in fact, he needs to calculate the quantity of really big numbers that are not greater than n.

Ivan tried to do the calculations himself, but soon realized that it's too difficult for him. So he asked you to help him in calculations.

Input

The first (and the only) line contains two integers n and s (1 ≤ n, s ≤ 1018).

Output

Print one integer — the quantity of really big numbers that are not greater than n.

Examples
input
12 1
output
3
input
25 20
output
0
input
10 9
output
1
Note

In the first example numbers 1011 and 12 are really big.

In the second example there are no really big numbers that are not greater than 25 (in fact, the first really big number is 30:30 - 3 ≥ 20).

In the third example 10 is the only really big number (10 - 1 ≥ 9).

题解

设n=k1*100...+k2*10....+kn*1

那么n减去各位数字和就是n'=9999..*k1+.....kn-1要求这个大于等于s

因为从1到n是递增的 所以k1,k2...kn都是增加的 自己举个例子就可以得出一个结论

n'序列这个数组是递增的!!! 所以 要在一个递增序列求大于等于s的个数

直接二分答案就可以啦。。。唉 我怎么没想到

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;	
ll n,s;
bool  check(ll x){
	ll tmp;
	while(x){
		int k=x%10;x/=10;
		tmp+=k;
	}
	if(x-tmp<s) return 0;//l=mid+1
	else return 1;//r=mid-1
}
int main(){
	int l,r;
	scanf("%lld%lld",&s,&n);
	l=1;r=n;
	while(l<=r){
		int mid=(l+r)/2;
		if(check(mid)) r=mid-1;
		else l=mid+1;
	}
	printf("%d",n-l+1);
	return 0;
}
D. Imbalanced Array
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given an array a consisting of n elements. The imbalance value of some subsegment of this array is the difference between the maximum and minimum element from this segment. The imbalance value of the array is the sum of imbalance values of all subsegments of this array.

For example, the imbalance value of array [1, 4, 1] is 9, because there are 6 different subsegments of this array:

  • [1] (from index 1 to index 1), imbalance value is 0;
  • [1, 4] (from index 1 to index 2), imbalance value is 3;
  • [1, 4, 1] (from index 1 to index 3), imbalance value is 3;
  • [4] (from index 2 to index 2), imbalance value is 0;
  • [4, 1] (from index 2 to index 3), imbalance value is 3;
  • [1] (from index 3 to index 3), imbalance value is 0;

You have to determine the imbalance value of the array a.

Input

The first line contains one integer n (1 ≤ n ≤ 106) — size of the array a.

The second line contains n integers a1, a2... an (1 ≤ ai ≤ 106) — elements of the array.

Output

Print one integer — the imbalance value of a.

Example
input
3
1 4 1
output
9

题解

求所有区间内最大值-最小值的和

如果朴素做法 肯定是n^2 过不去的

最好是log^2n才可以过掉 其实统计每个区间的最大最小值差

换种思路 算出每个数字 在各个区间出现为最大的次数和出现为最小的次数

显然答案为 每个数 最大的次数*这个数-最小的次数*这个数

统计次数用RMQ实现 没写代码。。

E题 01tire树

F题 线段树+优化

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章