目录
A. XXXXX
题意:给长度为n的数组A,问能否选出一个子数组使得子数组的和模X不为0,要求子数组的和尽量大。
思路:如果A[i] % x 0,则无子数组满足要求,若数组和模X不为0,则答案为n,否则只要找到第一个模X不为0的A[i]和最后一个两者对比长度就可以。
AC代码:
/*---------------------------------
*File name: A.cpp
*Creation date: 2020-06-14 01:31
*Link: https://codeforces.com/contest/1364/problem/A
*-------------------------------*/
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define pb push_back
#define LL long long
#define PII pair<int, int>
#define Pque priority_queue
using namespace std;
const int maxn = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
const double EPS = 1e-8;
int main(){
int t;
scanf("%d", &t);
while(t--){
int n, x;
scanf("%d %d", &n, &x);
vector<int> a(n);
int sum = 0;
bool flag = 0;
for(int i = 0; i < n; ++i) scanf("%d", &a[i]), sum += a[i], flag |= (a[i] % x != 0);
if(sum % x != 0) printf("%d\n", n);
else if(!flag) printf("-1\n");
else{
int pre, suf;
pre = n - 1, suf = 0;
for(int i = 0; i < n; ++i){
if(a[i] % x != 0){
pre = i;
break;
}
}
for(int i = n - 1; i >= 0; --i){
if(a[i] % x != 0){
suf = i;
break;
}
}
int ans = max(n - 1 - pre, suf);
printf("%d\n", ans);
}
}
return 0;
}
B. Most socially-distanced subsequence
题意:给长度为N的数组A,问能否选出一个长度为K的子序列S,子序列S最大。输出选择的数。
思路:如果把数组A在二维图坐标系上标出,横坐标为位置,纵坐标为A[i],然后按顺序连接所有点,最后呈现一个折线图,很容易就发现,选择的点必定都是转折点X,X和X-1连成线段所在直线的斜率与X+1和X连成线段所在直线的斜率一个为正一个为负。
AC代码:
/*---------------------------------
*File name: A.cpp
*Creation date: 2020-06-13 22:51
*Link:
*-------------------------------*/
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define pb push_back
#define LL long long
#define PII pair<int, int>
#define Pque priority_queue
using namespace std;
const int maxn = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
const double EPS = 1e-8;
int main(){
int t;
scanf("%d", &t);
while(t--){
int n;
scanf("%d", &n);
vector<int> a(n);
vector<int> ans;
for(int i = 0; i < n; ++i) scanf("%d", &a[i]);
bool flag = a[1] > a[0];
ans.pb(a[0]);
for(int i = 1; i < n; ++i){
if(i == n - 1){
ans.pb(a[i]);
break;
}
bool tmp = a[i + 1] > a[i];
if(tmp == flag) continue;
else {
flag ^= 1;
ans.pb(a[i]);
}
}
printf("%d\n", ans.size());
for(int i = 0; i < ans.size(); ++i) printf("%d%c", ans[i], i == ans.size() - 1? '\n' : ' ');
}
return 0;
}
C. Ehab and Prefix MEXs
题意:给出长度为N的数组A,要求构造出一个数组B,对于任意一个B[i],要求MEX{B[1], B[2], B[3], ...... , B[i]} = A[i]。MEX(...)定义为:子数组B[1] ~ B[i]中没有出现的非负数中的最小值。
思路:由于输入条件()的限制,导致这题必定是没有构造不出的情况,因为只有A数组为:1 2 3 4 2,类似这样的情况出现时才无法构造。即A[i] < A[j], i > j 的情况出现才会无法构造。且同时因为输入条件()的限制,所以用于构造的数必定小于n,用两个set:S和U分别存还没有使用过的数和没有出现过且没有用于构造B数组的数。当时,则代表在1~ i - 1之中,0~已经全部出现,因此可以腾出一个位置去填其他数,那么肯定是填U中的数更佳,因为这样有利于后面数组的填充,这就是为什么样例3中B[2] = 2的原因。如果,那肯定时填*S.begin()。
AC代码:
/*---------------------------------
*File name: A.cpp
*Creation date: 2020-06-13 22:51
*Link:
*-------------------------------*/
#include<set>
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define pb push_back
#define LL long long
#define PII pair<int, int>
#define Pque priority_queue
using namespace std;
const int maxn = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
const double EPS = 1e-8;
int a[maxn];
int b[maxn];
bool vis[maxn];
int main(){
int n;
scanf("%d", &n);
int Max = -1;
int x;
map<int, int> mp;
for(int i = 1; i <= n; ++i){
scanf("%d", &a[i]);
mp[a[i]] = i;
}
set<int> s, u;
for(int i = 0; i <= n; ++i) {
s.insert(i);
if(mp[i] == 0) u.insert(i);
}
for(int i = 1; i <= n; ++i){
int x = a[i] - 1;
if(*s.begin() > x){
b[i] = *u.begin();
u.erase(u.begin());
if(s.find(b[i]) != s.end())s.erase(b[i]);
}
else{
b[i] = *s.begin();
if(s.find(b[i]) != s.end())s.erase(b[i]);
if(u.find(b[i]) != u.end())u.erase(b[i]);
}
}
for(int i = 1; i <= n; ++i) printf("%d ", b[i]); printf("\n");
return 0;
}