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 imes 10leqslant n),一定可以,因为可以有一个十位上是 (d) 和个位是 (d) 的数组成。
- 当 (d imes 10geqslant 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
");
}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
");
}else{
printf("NO
");
}
}
}
}
}
C、Nezzar and Symmetric Array
题意:
给出一个长度为 (2 imes n) 的数组 (d),其中
问是否存在一个长度为 (2 imes 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 imes a_{n})
(a_{n-2}=d_{n-2}/4+2 imes 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
");
}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
");
}else{
printf("NO
");
}
}
}
}
D、Nezzar and Board
题意:
给一个数组 (a),可以选取数组中任意两个数 (a_{i}、a_{j}),把 (a_{i} imes 2-a_{j}) 放入数组中,问你经过无数次操作,是否可以让数字 (num) 在数组中。
想法:
- 把 (2 imes 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} imes d_{1}+k_{2} imes d_{2}+......+k_{n-1} imes d_{n-1}+k_{n} imes d_{n})表示。
- 那么我们只需要判断 (a_{i}+k_{1} imes d_{1}+k_{2} imes d_{2}+......+k_{n-1} imes d_{n-1}+k_{n} imes d_{n}=num) 是否有可能即可。
- 裴蜀定理:设 (a_{1},a_{2},a_{3}......a_{n})为 (n) 个整数,(d) 是它们的最大公约数,那么存在整数 (x_{1}......x_{n}) 使得(x_{1} imes a_{1}+x_{2} imes a_{2}+...x_{n} imes 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;
}