[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題 線段樹+優化

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