Codeforces Round #698 (Div. 2)(A、B、C、D)

Solved

  • A、Nezzar and Colorful Balls
  • B、Nezzar and Lucky Number
  • C、Nezzar and Symmetric Array
  • D、Nezzar and Board

A、Nezzar and Colorful Balls

数量最多的数字的数量即是答案。

int a[105];
int num[105];
int main()
{
    int T,n;
    cin>>T;
    while(T--){
        cin>>n;
        mem(num,0);
        int ans=0;
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            num[a[i]]++;
            ans=max(ans,num[a[i]]);
        }
        cout<<ans<<endl;
    }
}

B、Nezzar and Lucky Number

题意:
\(d\)\(lucky\ number\),判断一个数 \(n\) 是否可以由几个正整数组成(这些正整数中,每个数至少有一位包括 \(d\) )。

想法:

  • \(d\times 10\leqslant n\),一定可以,因为可以有一个十位上是 \(d\) 和个位是 \(d\) 的数组成。
  • \(d\times 10\geqslant n\),我们直接暴力判断,也就是由多个 \(d\) 和一个个位数包括 \(d\) 的数组成。

代码

int a[10500];
int num[15];
int main()
{
    int T,q,d;
    cin>>T;
    while(T--){
        cin>>q>>d;
        for(int i=1;i<=q;i++){
            scanf("%d",&a[i]);
        }
        for(int i=1;i<=q;i++){
            if(a[i]>=d*10){
                printf("YES\n");
            }else{
                int k=0;
                for(int j=1;j<=9;j++){
                    if((a[i]-j*d)%10==d){
                        k=1;
                        break;
                    }
                }
                if(k||a[i]%10==d||a[i]%d==0||a[i]/10==d){
                    printf("YES\n");
                }else{
                    printf("NO\n");
                }
            }
        }
    }
}

C、Nezzar and Symmetric Array

题意:
给出一个长度为 \(2\times n\) 的数组 \(d\),其中

$d_{i}=\sum^{2n}_{j=1} \left| a_{i}-a_{j}\right| $

问是否存在一个长度为 \(2\times n\) 的数组 \(a\) ,满足上述的数组 \(d\),且 \(a\) 数组满足条件 对于 \(a_{i}\),一定存在 \(a_{j}=-a_{i}\)。且 \(a\) 数组中没有重复数组。

想法:

  • 对于每对相反的 \(a_{i}\)\(a_{j}\),我们可以发现他们的 \(d\) 值是一样的,那么我们可以把题目转化为求一个长度为 \(n\) 的数组且数组内元素都为正且不相同。那么 \(d\) 也就变成了一个长度为 \(n\) 的数组。
  • 接下来考虑怎么求 \(a\) ,可以设出来 \(0<a_{1}<a_{2}<a_{3}<......<a_{n}\),那么接下来我们可以去求这个数组了。
  • 发现数组 \(a\) 的递推关系:
    \(a_{n}=d_{n}/4\)
    \(a_{n-1}=d_{n-1}/4+2\times a_{n}\)
    \(a_{n-2}=d_{n-2}/4+2\times a_{n-1}\)
    很显然上述的 \(d\)也需要按升序排序。
  • 最后去求数组 \(a\),只要 \(a\) 数组全部为正整数且无重复,答案即为 \(YES\)
  • 需要特判 \(n=1\)

代码:

ll d[200500];
ll a[100500];
set<ll>st;
vector<ll>v;
bool cmp(ll a,ll b)
{
    return a>b;
}
int main()
{
    int T,n;
    cin>>T;
    while(T--){
        st.clear();
        v.clear();
        scanf("%d",&n);
        for(int i=1;i<=2*n;i++){
            scanf("%lld",&d[i]);
            st.insert(d[i]);
        }
        if(st.size()!=n){
            printf("NO\n");
        }else{
            set<ll>::iterator it;
            int k=1;
            for(it=st.begin();it!=st.end();it++){
                v.push_back(*it);
                if(*it%2==1)k=0;
            }
            sort(v.begin(),v.end(),cmp);
            st.clear();
            int pos=2*n;
            ll pre=0;
            for(int i=0;i<n;i++){
                if((v[i]-pre)%pos!=0){
                    k=0;
                    break;
                }else{
                    a[i]=(v[i]-pre)/pos;
                    //cout<<a[i]<<endl;
                    st.insert(a[i]);
                    if(a[i]<=0){
                        k=0;
                        break;
                    }
                    pre+=2*a[i];
                    pos-=2;
                }
            }
            if(st.size()!=n)k=0;
            if(k){
                printf("YES\n");
            }else{
                printf("NO\n");
            }
        }
    }
}

D、Nezzar and Board

题意:
给一个数组 \(a\),可以选取数组中任意两个数 \(a_{i}、a_{j}\),把 \(a_{i}\times 2-a_{j}\) 放入数组中,问你经过无数次操作,是否可以让数字 \(num\) 在数组中。

想法:

  • \(2\times a_{i}-a_{j}\) 变成 \(a_{i}+a_{i}-a_{j}\),接下来用数组 \(d\) 去表示 \({a_{2}-a_{1} 、a_{3}-a_{2} 、a_{4}-a_{3} 、a_{5}-a_{4}...}\)
  • 接下来可以发现对于任何 \(a_{i}-a_{j}\),都可以通过数组 \(d\) 中元素加上系数后表示,即 \(k_{1}\times d_{1}+k_{2}\times d_{2}+......+k_{n-1}\times d_{n-1}+k_{n}\times d_{n}\)表示。
  • 那么我们只需要判断 \(a_{i}+k_{1}\times d_{1}+k_{2}\times d_{2}+......+k_{n-1}\times d_{n-1}+k_{n}\times d_{n}=num\) 是否有可能即可。
  • 裴蜀定理:设 \(a_{1},a_{2},a_{3}......a_{n}\)\(n\) 个整数,\(d\) 是它们的最大公约数,那么存在整数 \(x_{1}......x_{n}\) 使得\(x_{1}\times a_{1}+x_{2}\times a_{2}+...x_{n}\times a_{n}=d\)
  • 那么我们只需要判断 \(num-a_{i}\) 是否为数组 \(d\) 中所有元素的最大公约数的倍数即可。可以直接用 \(num-a_{1}\) 去判断,因为 \(a_{i}\) 的变化可以通过 \(k\) 的变化去改变。

代码:

ll gcd(ll a,ll b){ if(b==0)return a;return gcd(b,a%b);}
ll x[maxn];
ll n,k;
int main()
{
    int T;
    cin>>T;
    while(T--){
        cin>>n>>k;
        for(int i=1;i<=n;i++){
            scanf("%lld",&x[i]);
        }
        ll g=x[2]-x[1];
        for(int i=3;i<=n;i++){
            g=gcd(g,x[i]-x[i-1]);
        }
        if((k-x[1])%g==0)puts("YES");
        else puts("NO");
    }
    return 0;
}
posted @ 2021-01-29 20:52  hachuochuo  阅读(81)  评论(0编辑  收藏  举报