A. Nezzar and Colorful Balls
题意:签到题。
思路:求最大的相同值的数量。
AC代码:
#include <iostream>
#include <bits/stdc++.h>
#include <unordered_map>
#define int long long
#define mk make_pair
#define gcd __gcd
using namespace std;
const double eps = 1e-10;
const int mod = 1e9+7;
const int N = 3e6+7;
int n,m,k,t = 1,cas = 1;
int a[N],b[N];
signed main(){
cin>>t;
while(t--){
cin>>n;
for(int i = 0 ; i < n ; i ++) cin>>a[i];
int cnt = 1;
int maxx = 1;
for(int i = 1 ; i < n ; i ++){
if(a[i] == a[i-1]) cnt ++;
else cnt = 1;
maxx = max(maxx,cnt);
}
cout<<maxx<<endl;
}
return 0;
}
B. Nezzar and Lucky Number
题意:给出一些数和一个d。判断这个数能不能等于 任意个 数位中含有d的数 的和。
思路:对于大于 d10的数。可以一直减 d,直到变成 d10+x。那显然可以。 对于小于 d10 的数。 那么久只能由 d,x10+d。这两种数组成。那就不断的减去d的倍数。判断剩下的能不能被10整除。
AC代码:
#include <iostream>
#include <bits/stdc++.h>
#include <unordered_map>
#define int long long
#define mk make_pair
#define gcd __gcd
using namespace std;
const double eps = 1e-10;
const int mod = 1e9+7;
const int N = 3e6+7;
int n,m,k,t = 1,cas = 1;
int a[N],b[N];
signed main(){
cin>>t;
while(t--){
cin>>n>>m;
for(int i = 0 ; i < n ; i ++) cin>>a[i];
for(int i = 0 ; i <n ; i ++){
int flag = 0;
if(a[i] >= m*10) flag = 1;
for(int j = 1 ; j <= 100 ; j ++){
if(a[i] >= j*m && ( (a[i] - j*m)%10 == 0)){
flag = 1;
}
}
puts(flag? "YES" :"NO");
}
}
return 0;
}
C. Nezzar and Symmetric Array
题意:原数组是一个对称数组。所有元素 互不相同!并且成对出现。有x 就有 -x。现在给出d数组。 d i = ∑ j = 1 2 n ∣ a i − a j ∣ d_{i}=\sum^{2n}_{j=1}|a_i−a_j| di=∑j=12n∣ai−aj∣问能不能找到一个满足条件的原数组。
思路:观察可以发现。 ∣ a i − a j ∣ |a_i−a_j| ∣ai−aj∣+ ∣ a i + a j ∣ |a_i+a_j| ∣ai+aj∣ == max( ∣ a i ∣ |a_i| ∣ai∣, ∣ a j ∣ |a_j| ∣aj∣)*2。也就是不管当前的数是更大的那个还是更小的那个。怎么减都是更大的那个数的两倍。那么其实有这一点就可以推出原数组了。最大值肯定是就是 a[1] = max(di)/n。然后 a[2] = 第二大的数 - max / (n-1) 依次类推。但是要注意很多坑。这题看完题就有思路。可惜一直踩坑踩到了最后10分钟。上述过程是一个累加的过程。 也就是 第i大的数 要减去 第i-1大的数,第i-2大的数 … 。也就是前面的数的和。那么要保证d[i] - 这个sum不出现负数。不出现奇数。不出现0。因为题目要求。同时也不能出现相同的值。少考虑一个坑就很搞人心态。就重复这个过程从最大值推到最小值就行了。如果一路都是合法的就是合法的。并且原数组是唯一的(排序后是唯一的)。
AC代码:
#include <iostream>
#include <bits/stdc++.h>
#include <unordered_map>
#define int long long
#define mk make_pair
#define gcd __gcd
using namespace std;
const double eps = 1e-10;
const int mod = 1e9+7;
const int N = 3e6+7;
int n,m,k,t = 1,cas = 1;
int a[N],b[N];
signed main(){
cin>>t;
while(t--){
cin>>n;
int flag = 1;
for(int i = 0 ; i < 2*n ; i ++){
cin>>a[i];
if(a[i] % 2 || a[i] <= 0) flag = 0; // 不能为 0 奇数 负数
}
sort(a,a+2*n,greater<int>() );
int sum = 0;
int cnt = 0;
for(int i = 0 ; i < 2*n ; i += 2){
int now = a[i]-sum;
if(a[i] != a[i+1]) flag = 0; // 数据是成对出现的,所以 a[i]必须等于a[i+1]
if(i > 0 && a[i] == a[i-1]) flag = 0; // 不能出现相同值
if(now % 2 || now <= 0 ) flag = 0; // 这里也不能出现奇数 负数 0
if(now % (n-cnt) != 0 ) flag = 0; // 必须整除才行
if(flag == 0) break;
sum += now/(n-cnt); // 前面已经减掉的数
cnt ++;
}
puts(flag ? "YES" : "NO");
}
return 0;
}
D. Nezzar and Board
题意:给定一个数组。只有一种操作。选择两个数x,y。然后数组增加一个新数 2*x-y。问能不能通过这种操作合成出 k。
思路参考:https://www.cnblogs.com/HotPants/p/14344386.html
思路: 先变换一下操作。2*x-y = x+(x-y),然后说是。可以变成 x 加上 任意两数的差值的任意线性组合(暂时没证出来)。所以最后的k 也就是 a[i] + 任意两数的差的任意线性组合。这时候就可以用贝祖定理(裴蜀定理)。所以对所有元素求一个gcd。判断 (k-a[i])%gcd 是否等于0就行了。 然后对于这道题。其实判断a[1]就行了。因为 a[i] 肯定也和k一样,可以由任意差的任意组合出来。即(a[i]-a[j])%gcd == 0 一定成立。所以只需要判断 (k-a[1])%gcd 就行了。
AC代码:
#include <iostream>
#include <bits/stdc++.h>
#include <unordered_map>
#define int long long
#define mk make_pair
#define gcd __gcd
using namespace std;
const double eps = 1e-10;
const int mod = 1e9+7;
const int N = 3e6+7;
int n,m,k,t = 1,cas = 1;
int a[N],b[N];
signed main(){
cin>>t;
while(t--){
cin>>n>>m;
for(int i = 0 ; i < n ; i ++) cin>>a[i];
int g = a[1]-a[0];
for(int i = 1 ; i < n ; i ++) g = gcd(a[i]-a[i-1],g);
puts((m-a[0]) % g == 0 ? "YES" :"NO");
}
return 0;
}