A. XXXXX
倍数-非 倍数 = 非 倍数,知道这个就很好做了,先求全部的和,然后找到首尾最近的那个不是 倍数 的位置减去就行。
AC代码:
const int N = 2e5 + 50;
int n, m, x;
int a[N];
ll sum;
int main()
{
int t;
sd(t);
while (t--)
{
sdd(n, x);
sum = 0;
rep(i, 1, n)
{
sd(a[i]);
sum += a[i];
}
if (sum % x != 0)
{
pd(n);
continue;
}
int pos1 = 0, pos2 = 0;
int ans = n;
rep(i, 1, n)
{
pos1++;
if (a[i] % x != 0)
break;
}
per(i, n, 1)
{
pos2++;
if (a[i] % x != 0)
break;
}
if (pos1 == n && pos2 == n)
{
puts("-1");
continue;
}
ans = n - min(pos1, pos2);
pd(ans);
}
return 0;
}
B. Most socially-distanced subsequence
两个拐点之间的差绝对值和是一定的,只取拐点就是最短。
AC代码;
const int N = 2e5 + 50;
int n, m, k;
int p[N];
vector<int> ans;
int pos;
int main()
{
int t;
sd(t);
while (t--)
{
sd(n);
rep(i, 1, n)
sd(p[i]);
ans.clear();
ans.pb(p[1]);
rep(i, 1, n)
{
pos = i;
if (p[pos + 1] > p[i])
{
while (pos + 1 <= n && p[pos + 1] > p[pos])
pos++;
}
else if (p[pos + 1] < p[i])
{
while (pos + 1 <= n && p[pos + 1] < p[pos])
pos++;
}
ans.pb(p[pos]);
i = pos - 1;
if (pos == n)
break;
}
pd(ans.size());
rep(i, 0, ans.size() - 1)
printf("%d%c", ans[i], i == ans.size() - 1 ? '\n' : ' ');
}
return 0;
}
C. Ehab and Prefix MEXs
构造的话好构造,用 记录每个数是否出现和次数,把去重后的元素放到一个队列中。从 开始找,如果没有出现就填入这个数字。然后就是判断无解的情况, 数组应该把 数组这个位置元素前没出现的数字给填一遍。
AC代码:
const int N = 2e5 + 50;
int a[N], b[N];
map<int, int> mp;
int n;
int main()
{
sd(n);
queue<int> q;
rep(i, 1, n)
{
sd(a[i]);
mp[a[i]]++;
if (mp[a[i]] == 1)
q.push(a[i]);
}
bool flag = 1;
int ans = -1;
if (a[1] > 1)
{
puts("-1");
return 0;
}
a[0] = a[1];
rep(i, 1, n)
{
if (a[i] == a[i - 1])
{
ans++;
while (mp[ans] > 0)
ans++;
b[i] = ans;
}
else
{
b[i] = a[i - 1];
if (q.front() != b[i])
{
flag = 0;
break;
}
q.pop();
if (b[i] < a[i] - 1 && ans < a[i] - 1)
{
flag = 0;
break;
}
}
}
if (!flag)
puts("-1");
else
{
rep(i, 1, n)
cout << b[i] << ' ';
puts("");
}
return 0;
}