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\),其中
问是否存在一个长度为 \(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;
}
标签:Nezzar,cin,int,698,Codeforces,times,数组,Div,ll 来源: https://www.cnblogs.com/ha-chuochuo/p/14346993.html