Codeforces Round 948 (Div. 2)题解
A.Little Nikita
题意:
\(n\)步操作,\(+1\)或\(-1\),最终结果是否等于\(m\)
思路:
设\(+1\)的操作次数为\(x\),\(-1\)的操作次数为\(y\)
\((n-m)\)和\((n+m)\)均为偶数,即\(n\)和\(m\)均为偶数或同为奇数,且\(n>=m\)
代码:
void solve()
{
int n, m;
cin >> n >> m;
if (((n & 1) == (m & 1)) && n >= m)
{
cout << "Yes" << endl;
}
else
{
cout << "No" << endl;
}
}
B. Binary Colouring
题意:
构造题。给定一个\(x\),使用一个包含\(-1,0,1\)的数组按照二进制的方式表示\(x\),且数组中不能连续出现不为零的情况
思路:
考虑 \([a_{l},a_{r}]\) 全为\(1\)时,等价为 $a_{l}=-1,a_{r+1}=1,\forall x \in [a_{l+1},a_{r}]=0 $
通过上述方式构造,可能会出现相邻位置同时不为零的情况,讨论\(a_{i},a_{i+1}\)
\(a_{i}=-1,a_{i+1}=1\),等价为 \(a_{i}=1,a_{i+1}=0\)
\(a_{i}=1,a_{i+1}=-1\),等价为 \(a_{i}=-1,a_{i+1}=0\)
代码:
const int N = 32;
int a[N], ans[N];
void solve()
{
int x;
cin >> x;
for (int i = 0; i <= 31; i++)
{
a[i] = 0;
ans[i] = 0;
a[i] = (x >> i) & 1;
}
for (int i = 0; i <= 31; i++)
{
if (a[i] == 1)
{
int len = 0;
while (i <= 31 && a[i] == 1)
{
len++;
i++;
}
ans[i] = 1;
ans[i - len] = -1;
}
}
for (int i = 0; i <= 30; i++)
{
if (ans[i] == -1 && ans[i + 1] == 1)
{
ans[i] = 1, ans[i + 1] = 0;
}
if (ans[i] == 1 && ans[i + 1] == -1)
{
ans[i] = -1, ans[i + 1] = 0;
}
}
cout << 32 << endl;
for (int i = 0; i <= 31; i++)
{
cout << ans[i] << " ";
}
cout << endl;
}
C.Nikita and LCM
题意:
给定一个数组\(A\),找出一个最长的子数组,使其子数组的最小公倍数未在原数组中出现过
思路:
设\(mx=MAX(a_1,a_2,...,a_{n})\),考虑两种情况,通过枚举\(a_{i}\)
-
存在 $ a_{i} \nmid mx$ 的情况,此时\(LCM(mx,a_{i})>mx\),即有\(LCM(a_1,a_2,...,a_{n})> a_n\)
此时答案为\(n\)
-
不存在$ a_{i} \nmid mx$ 的情况,即任意\(a_{i}\)都是\(mx\)的因数
对任意子数组\(a_{p1},a_{p2},...,a_{pm}\)进行\(LCM\)运算都是\(mx\)的因数
考虑枚举\(mx\)的因数\(t\)
$t \notin A $并且存在 \(a_{p1},a_{p2},...,a_{pm}\)使得 \(LCM(a_{p1},a_{p2},...,a_{pm})=t\)
得到一个合法答案\(m\),维护最大值即可
考虑子数组的选择,因为 \(LCM(a_{p1},a_{p2},...,a_{pm})=t\),则子数组都是\(t\)的因数,只需要在枚举\(a_{i}\)时判断是否整除\(t\)即可
代码
const int N = 2e3 + 5;
ll a[N];
int n, ans = 0;
unordered_map<int, int> mp; // 记录是否出现过
ll lcm(ll a, ll b)
{
return a / __gcd(a, b) * b;
}
void check(ll t)
{
int res = 0;
ll tmp = 1;
for (int i = 1; i <= n; i++)
{
if (t % a[i] == 0)
{
tmp = lcm(tmp, a[i]);
res++;
}
}
if (tmp == t)
{
ans = max(ans, res);
}
}
void solve()
{
ans = 0;
mp.clear();
cin >> n;
ll mx = 0;
ll cnt = 1; // 所有数的lcm
for (int i = 1; i <= n; i++)
{
cin >> a[i];
mp[a[i]]++;
mx = max(mx, a[i]);//维护最大值
}
for (int i = 1; i <= n; i++)
{
if (mx % a[i] != 0)
{
cout << n << endl;
return;
}
}
for (int i = 1; i * i <= mx; i++)
{
if (mx % i == 0)
{
if (mp[i] == 0)
{
check(i);
}
if (mp[mx / i] == 0)
{
check(mx / i);
}
}
}
cout << ans << endl;
}

浙公网安备 33010602011771号