A - Even But Not Even
B - Array Sharpening
C - Mind Control
D - Irreducible Anagrams
A - Even But Not Even
题意:给长度为n的一个数字串,求其子串符合子串每个数字和为偶数但子串是奇数。答案不唯一
思路:其实根本不用考虑偶数,符合条件的串一定是奇数为偶数个数,且最后一位是奇数。由于答案不唯一,我们只考虑一种情况,有两个奇数的子串。只要够两个奇数就直接输出任意两个奇数就行,不够就输出NO即可。
#include<bits/stdc++.h>
#define debug(x) cout <<#x<<" = "<<x<<endl
#define gg cout <<"---------------QAQ---------------"<<endl
#define fi first
#define se second
#define pb push_back
#define ll long long
#define inf 0x3f3f3f3f
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;
typedef pair<int,int> pii;
const int N = 266666, maxn = 1666666;
void FAST(){ios::sync_with_stdio(false);cin.tie(0);}
void solve()
{
int n; string s;
cin >>n>>s;
vector<int> ans;
for(int i = 0; i < n; ++i) {
if((s[i]-'0')%2 == 1) ans.pb(i);
if(ans.size() >= 2) {
cout<<s[ans[0]]<<s[ans[1]]<<endl; return ;
}
}
cout<<"-1"<<endl;
}
int main()
{
int t;
cin>>t;
while(t--)
solve();
return 0;
}
B - Array Sharpening
题意:给一个长度为n的非零数组,求是否能把数组变成a1<a2<a3…< ak>ak+1>…an。能对数组中任意元素进行减减操作,但不能变成负数。
思路:我们找出最小的一种可能和原数组进行对比,如果原数组中有元素大于最小的可能,输出NO,否则就输出YES。最小的可能就是0 1 2 3 … (k+1)/2 … 3 2 1 0。这种还需要考虑一下数组是偶数个的情况,如果是偶数个。例如0 1 1 0,我们需要把两个中间的数的最大的一个作为ak,类似0 2 1 0.
#include<bits/stdc++.h>
#define debug(x) cout <<#x<<" = "<<x<<endl
#define gg cout <<"---------------QAQ---------------"<<endl
#define fi first
#define se second
#define pb push_back
#define SZ(x) ((int)x.size())
#define ll long long
#define L(i,u) for (register int i=head[u]; i; i=nxt[i])
#define rep(i,a,b) for (register int i=(a); i<=(b); i++)
#define per(i,a,b) for (register int i=(a); i>=(b); i--)
#define inf 0x3f3f3f3f
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;
typedef unsigned int ui;
typedef pair<int,int> pii;
typedef vector<int> Vi;
template<class T> inline void read(T &x){
x=0; char c=getchar(); int f=1;
while (!isdigit(c)) {if (c=='-') f=-1; c=getchar();}
while (isdigit(c)) {x=x*10+c-'0'; c=getchar();} x*=f;
}
const int N = 366666, maxn = 1666666;
void FAST(){ios::sync_with_stdio(false);cin.tie(0);}
int a[N];
void solve()
{
int n; scanf("%d", &n);
for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
for(int i = 1; i < (n+1)/2; ++i) {
int l = i, r = n-l+1;
if(a[l]<l-1||a[r]<l-1) {
puts("NO"); return ;
}
}
if(n%2 == 1) {
if(a[(n+1)/2]<(n+1)/2-1) {
puts("NO"); return ;
}
}
else {
int l = (n+1)/2, r = n-l+1;
if(max(a[l], a[r])<=l-1||min(a[l], a[r])<l-1) {
puts("NO"); return ;
}
}
puts("YES");
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
solve();
return 0;
}
C - Mind Control
题意: 有n个人选数,你在m的位置,只能选择第一个或最后一个,选完之后就没有删除。你可以控制k个人的选择,在你的操作下最坏情况能选择的最大的数是多少。
思路: 我们肯定选择操作我们前面的k个人,k可能大于m,先和m-1取最小。现在枚举让这k个人选择前i和后k-i个数。然后再枚举我们前面的m-k-1个不能被操作的人的可能性,让他们取删除后的前j个和后m-k-1-j个。然后就是我们选了,注意我们此时肯定选择最大的数,然后和前面的m-k-1次枚举操作取最小,最后再和k次操作取最大就是答案。选择这个思路是因为n和m的值较小,总的就是两次枚举。
#include<bits/stdc++.h>
#define debug(x) cout <<#x<<" = "<<x<<endl
#define gg cout <<"---------------QAQ---------------"<<endl
#define fi first
#define se second
#define pb push_back
#define SZ(x) ((int)x.size())
#define ll long long
#define L(i,u) for (register int i=head[u]; i; i=nxt[i])
#define rep(i,a,b) for (register int i=(a); i<=(b); i++)
#define per(i,a,b) for (register int i=(a); i>=(b); i--)
#define inf 0x3f3f3f3f
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;
typedef unsigned int ui;
typedef pair<int,int> pii;
typedef vector<int> Vi;
template<class T> inline void read(T &x){
x=0; char c=getchar(); int f=1;
while (!isdigit(c)) {if (c=='-') f=-1; c=getchar();}
while (isdigit(c)) {x=x*10+c-'0'; c=getchar();} x*=f;
}
const int N = 366666, maxn = 1666666;
void FAST(){ios::sync_with_stdio(false);cin.tie(0);}
int a[N];
void solve()
{
int n, m, k; scanf("%d%d%d", &n, &m, &k);
for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
int ans = 0;
k = min(m-1, k);
for(int i = 0; i <= k; ++i) {
int l = 1+i, r = n-(k-i);
int t = m-k-1;
int res = inf;
for(int j = 0; j <= t; ++j) {
int tl = l+j, tr = r-(t-j);
res = min(res, max(a[tl], a[tr]));
}
ans = max(ans, res);
}
printf("%d\n", ans);
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
solve();
return 0;
}
D. Irreducible Anagrams
看了一个小时没看懂啥意思,wtcl!
题意:https://www.cnblogs.com/1625–H/p/12254833.html
思路:我们声明满足下面条件的字符串存在irreducible anagram
1 长度等于1
2 首字符和尾字符不同
3 字符串包含至少三种不同的字符
#include<bits/stdc++.h>
#define debug(x) cout <<#x<<" = "<<x<<endl
#define gg cout <<"---------------QAQ---------------"<<endl
#define fi first
#define se second
#define pb push_back
#define SZ(x) ((int)x.size())
#define ll long long
#define L(i,u) for (register int i=head[u]; i; i=nxt[i])
#define rep(i,a,b) for (register int i=(a); i<=(b); i++)
#define per(i,a,b) for (register int i=(a); i>=(b); i--)
#define inf 0x3f3f3f3f
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;
typedef unsigned int ui;
typedef pair<int,int> pii;
typedef vector<int> Vi;
template<class T> inline void read(T &x){
x=0; char c=getchar(); int f=1;
while (!isdigit(c)) {if (c=='-') f=-1; c=getchar();}
while (isdigit(c)) {x=x*10+c-'0'; c=getchar();} x*=f;
}
const int N = 366666, maxn = 1666666;
void FAST(){ios::sync_with_stdio(false);cin.tie(0);}
char s[N];
int n, sum[N][26], q, l, r;
void solve()
{
cin >>(s+1); n = strlen(s+1);
for(int i = 1; i <= n; ++i) {
for(int j = 0; j < 26; ++j) sum[i][j] = sum[i-1][j];
sum[i][s[i]-'a']++;
}
cin >> q;
while(q--) {
cin >>l>>r;
int ans = 0;
for(int i = 0; i < 26; ++i) ans+=(sum[r][i]-sum[l-1][i]>0);
if(l == r||ans>=3||s[l]!=s[r]) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
int main()
{
FAST();
solve();
return 0;
}