Codeforces Round #698 (Div. 2)

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=12naiaj问能不能找到一个满足条件的原数组。

思路:观察可以发现。 ∣ a i − a j ∣ |a_i−a_j| aiaj+ ∣ 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值