CF1477A Nezzar and Board 题解

题意

  • 给出数列 S={ai} 和整数 k,求是否能通过下面的操作使得 kS
  • 操作:选取 x,yS,将 2xy 加入 S 中。

分析

  • 观察操作可以发现,2xy 实际上就是数轴上 y 关于 x 的对称点,因此这个操作只与 xy 在数轴上的相对位置有关,与具体位置(具体数值)无关。继续观察可以发现,如果 0S,那么就会有几个很好的性质:
  1. xS,那么 nxS,nZ
  2. x,yS,那么 x+yS
  • 为了可以利用这两条性质,我们可以将 S 变化为 S={aia1},并把 k 减去 a1(就相当于将数轴平移了)。此时 0S,因此在无限次进行操作之后,得到的就是 S 的整线性组合 S={x|x=mgcd(a2,a3,,an),mZ},判断 kS 即判断 gcd(a2,a3,,an)k,直接求解即可。

AC 代码

#include <bits/stdc++.h>
#define int long long
#define N 200005
using namespace std;
int n, k, a[N];
inline int read(int &x) {
char ch = x = 0;
int m = 1;
while (ch < '0' || ch > '9') {
ch = getchar();
if (ch == '-') m *= -1;
}
while (ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + ch - 48;
ch = getchar();
}
x *= m;
return x;
}
int gcd(int x, int y) {
if (y == 0) return x;
return gcd(y, x % y);
}
signed main() {
int T;
read(T);
while (T--) {
read(n), read(k);
for (int i = 1; i <= n; i++) read(a[i]);
sort(a + 1, a + 1 + n);
for (int i = 2; i <= n; i++) a[i] -= a[1]; //平移数轴
k -= a[1];
if (k == 0) { //避免取余 k
printf("YES\n");
continue;
}
a[1] = 0;
int g = a[2];
for (int i = 3; i <= n; i++) g = gcd(g, a[i]); //求解 gcd
if (k % g) printf("NO\n");
else printf("YES\n");
}
return 0;
}
posted @   HappyJaPhy  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示