复活!年后首场!本期封面是我自己AI弄的图
A - Milya and Two Arrays
题意
给两个所有数字出现次数都大于2的数组,问能不能修改排序之后对应位置相加得到新的数组使不同数字个数达到3
思路
直接计数就行了,不同的数字匹配一下就行
代码
//
// Created by Swan416 on 2025-02-02 22:32.
//
#include <bits/stdc++.h>
#define maxOf(a) *max_element(a.begin(),a.end())
#define minOf(a) *min_element(a.begin(),a.end())
#define all(a) a.begin(),a.end()
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void solve()
{
int n;
scanf("%d",&n);
vector<int> a(n),b(n);
map<int,int> mpa,mpb;
int cnta=0,cntb=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
mpa[a[i]]++;
if(mpa[a[i]]==1) cnta++;
}
for(int i=0;i<n;i++)
{
scanf("%d",&b[i]);
mpb[b[i]]++;
if(mpb[b[i]]==1) cntb++;
}
if(cnta>2 or cntb>2)
{
printf("YES\n");
return;
}
else if(cnta==2 and cntb==2)
{
printf("YES\n");
return;
}
else if(cnta==2 and cntb==1)
{
printf("NO\n");
return;
}
else if(cnta==1 and cntb==2)
{
printf("NO\n");
return;
}
else if(cnta==1 and cntb==1)
{
printf("NO\n");
return;
}
}
int main()
{
int T=1;
scanf("%d",&T);
while(T--)
{
solve();
}
return 0;
}
C - Customer Service
题意
有n个队列,每一秒你可以选择一个队列清零,然后按照给定的数组加数据,最大话最后所有队列大小的MEX值
思路
统计最长的后缀1的个数然后从小到大sort一下,然后贪心往下取就行,如果有大于1的数一定会导致MEX在这里断掉的
代码
//
// Created by Swan416 on 2025-02-02 23:21.
//
#include <bits/stdc++.h>
#define maxOf(a) *max_element(a.begin(),a.end())
#define minOf(a) *min_element(a.begin(),a.end())
#define all(a) a.begin(),a.end()
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void solve()
{
int n;
scanf("%d",&n);
vector<vector<int>> q(n);
for(int i=0;i<n;i++)
{
q[i].clear();
q[i].push_back(i);
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
int x;
scanf("%d",&x);
q[i].push_back(x);
}
}
vector<int> cnt(n+1,0);
for(int i=0;i<n;i++)
{
for(int j=n;j>0;j--)
{
if(q[i][j]!=1)
break;
cnt[i]++;
}
}
auto cmp=[&](vector<int>& x,vector<int>& y)
{
return cnt[x[0]]<cnt[y[0]];
};
sort(q.begin(),q.end(),cmp);
int now=0;
for(int i=0;i<n;i++)
{
int p=q[i][0];
if(cnt[p]>=now)
{
now++;
}
}
printf("%d\n",now);
}
int main()
{
int T=1;
scanf("%d",&T);
while(T--)
{
solve();
}
return 0;
}
B - Cost of the Array
题意
将长度为n的数列分成k个非空块,然后第偶数块拼在一起,让其与iota的结果最早不匹配
思路
特判,疯狂的特判
代码
//
// Created by Swan416 on 2025-02-02 23:35.
//
#include <bits/stdc++.h>
#define maxOf(a) *max_element(a.begin(),a.end())
#define minOf(a) *min_element(a.begin(),a.end())
#define all(a) a.begin(),a.end()
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void solve()
{
int n,k;
scanf("%d%d",&n,&k);
vector<int> a(n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
vector<int> b;
if(n==k)
{
for(int i=1;i<n;i+=2)
{
b.push_back(a[i]);
}
for(int i=0;i<b.size();i++)
{
if(b[i]!=i+1)
{
printf("%d\n",i+1);
return;
}
}
printf("%d\n",n/2+1);
return;
}
for(int i=1;i<n;i++)
{
if(a[i]!=1 and n-i+1>=k)
{
printf("1\n");
return;
}
}
printf("2\n");
}
int main()
{
int T=1;
scanf("%d",&T);
while(T--)
{
solve();
}
return 0;
}
D - Graph and Graph
题意
给你两张图,然后无限次操作:分别选当前点的邻居然后代价加上 ∣ u − v ∣ |u-v| ∣u−v∣,最小化总代价
思路
首先是无限次操作所以肯定是最后两个点在对应位置反复横跳使得每次操作代价都是加0,我们先标记图上可以作为最终状态的点:也就是两个图上的这个点存在共同邻居的点。然后跑一遍dijkstra就行了
代码
//
// Created by Swan416 on 2025-02-03 00:10.
//
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1145;
int n, s1, s2;
vector<int> G1[N], G2[N];
bool ok[N];
struct Node {
int x, y, cost;
bool operator>(const Node& other) const {
return cost > other.cost;
}
};
void solve() {
scanf("%d%d%d", &n, &s1, &s2);
int m1;
scanf("%d", &m1);
for (int i = 1; i <= n; ++i) {
G1[i].clear();
G2[i].clear();
}
for (int i = 0; i < m1; ++i) {
int u, v;
scanf("%d%d", &u, &v);
G1[u].push_back(v);
G1[v].push_back(u);
}
int m2;
scanf("%d", &m2);
for (int i = 0; i < m2; ++i) {
int u, v;
scanf("%d%d", &u, &v);
G2[u].push_back(v);
G2[v].push_back(u);
}
// 标记可以成为最终状态的点
memset(ok, 0, sizeof(ok));
for (int i = 1; i <= n; ++i) {
for (int j : G1[i]) {
if (find(G2[i].begin(), G2[i].end(), j) != G2[i].end()) {
ok[i] = true;
break;
}
}
}
// Dijkstra找最小成本到达最终状态点的成本
priority_queue<Node, vector<Node>, greater<Node>> pq;
map<pii, int> dist;
pq.push({s1, s2, 0});
dist[{s1, s2}] = 0;
ll ans = LLONG_MAX;
while (!pq.empty()) {
Node cur = pq.top();
pq.pop();
if (cur.cost > dist[{cur.x, cur.y}]) {
continue;
}
if (cur.x == cur.y && ok[cur.x]) {
ans = min(ans, (ll)cur.cost);
break;
}
for (int nx : G1[cur.x]) {
for (int ny : G2[cur.y]) {
int new_cost = cur.cost + abs(nx - ny);
if (dist.find({nx, ny}) == dist.end() || new_cost < dist[{nx, ny}]) {
dist[{nx, ny}] = new_cost;
pq.push({nx, ny, new_cost});
}
}
}
}
if (ans == LLONG_MAX) {
printf("-1\n");
} else {
printf("%lld\n", ans);
}
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
solve();
}
return 0;
}