目录
前言
今天ACM省赛选拔,只过了两题,太弱鸡了o(╥﹏╥)o
五个小时,纯纯坐牢,家人们,谁懂啊ε=ε=ε=(#>д<)ノ
其实有简单题是认真思考过的,但是太久没刷CF,中了它的圈套!
一、 Interesting Subarray
题意翻译
https://codeforces.com/problemset/problem/1270/B
给出一个数列,要求找出一段连续的子数列满足这个子数列的最大值与最小值之差不小于其元素个数(子数列可以是原数列)
题解:
第一遍没看出来什么方法,直接暴力加模拟,i,j 双重循环复杂度O(n*n),毫无疑问,时间超限。
后来看题解,其实应该先从小处入手(很多CF简单题都这样设套,一认真就输咯)
比如这题,max-min>=k,当k>=3时,max,min需要查找,顺序查找太复杂 时间超限:所以我们从k=2入手,两个字符相邻。假设a,b,若|a-b|>=2,则输出yes,反过来想,如果不存在符合情况,那么必然不存在|a-b|>=2. 所以我们简化了判断条件(很多题目都需要这样的转换思想,我刚开始就想复杂了)
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
int m;
cin>>m;
int cnt=0;
int a[200005]={0};
for(int j=1;j<=m;j++){
cin>>a[j];
}
for(int j=2;j<=m;j++){
if(abs(a[j]-a[j-1])>=2||abs(a[j-1]-a[j]>=2)){
cnt=1;
cout<<"YES\n"<<j-1<<" "<<j<<'\n';
break;
}
}
if(cnt==0)cout<<"NO\n";
}
return 0;
}
二、As Simple as One and Two
题意翻译
https://codeforces.com/problemset/problem/1276/A
给定一个字符串,要求你删除尽量少的字符,使得字符串中不存在一个子串为 one
或 two
。
注意,本题要求输出删除字符数与方案,并且有多组数据。
保证所有字符串的长度和 <=1.5*1e6
题解:
1.如果是twone类型,那么就删去o字符;
2.如果是tttwooo、oooneee这种,那么就删去中间的;
3.剩下就是one、two单独出现的,可以删去任意一个;
所以简化条件可知:
如果是twone那么就删去o字符
two删去w,one删去n
注意数组大小,字符数组开1.5e6+5,位置数组开2e5+5(好像是栈内数组只能开到4e5,用static开静态数组可以开到4e8)wa了好多发
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
for(int k=1;k<=n;k++){
char a[1500005]={'0'};
cin>>a;
int cnt=0;
int b[200005]={0};
for(int i=0;i<strlen(a);i++){
if(a[i]=='t'&&a[i+1]=='w'&&a[i+2]=='o'&&a[i+3]=='n'&&a[i+4]=='e'){
b[cnt]=i+2;
cnt++;
i+=4;
}
else if(a[i]=='t'&&a[i+1]=='w'&&a[i+2]=='o'){
//直接都去除w;
b[cnt]=i+1;
cnt++;
i+=2;
}
else if(a[i]=='o'&&a[i+1]=='n'&&a[i+2]=='e'){
//直接都去除n;
b[cnt]=i+1;
cnt++;
i+=2;
}
}
if(cnt==0)cout<<0<<'\n'<<'\n';
else {
cout<<cnt<<'\n';
for(int i=0;i<cnt;i++)cout<<b[i]+1<<" ";
cout<<'\n';
}
}
return 0;
}
三、 Reading Books (easy version)
题意翻译
https://codeforces.com/problemset/problem/1374/E1
Alice 和 Bob 一共有 n 本书要读。第 i 本书有三个属性:阅读时间 ti,ai(为 1 表示 Alice 喜欢这本书,为 0 表示 Alice 不喜欢),bi(为 1表示 Bob 喜欢这本书,为 0 表示 Bob 不喜欢)。
他们需要从这些书中选择若干本,满足
- 这些书中至少有 k 本是 Alice 喜欢的,至少有 k 本是 Bob 喜欢的。
- 阅读的总时间最小(总时间为选中的书的 ti 的总和)
输入格式
第一行两个整数 n和 k(1<=k<=n<=2e5)。
之后的 n 行,每行三个整数
ti , ai and bi (1≤ti≤1e4 1≤ti≤1e4, 0≤ai,bi≤1)。
输出格式
输出最小的时间 T。
如果无解,输出-1
。
题解:
分析题意可知,书的类型可分为三种:
1.A B 都喜欢;
2.只有A喜欢或只有B喜欢;
3.两者都不喜欢;(可直接排除,不加入计算)
计算总时间 运用贪心思想,每次选取满足条件的最短时间,但是1 和 2 的情况下条件不相同,所以需要转化一下:
将只有A喜欢的装入a数组,只有B喜欢的装入b数组,两者都喜欢的装入c数组
对a b 数组排序,然后从小到大两两合并加入到c数组,然后当成他俩都喜欢的书,时间为这两本书的和。最后对c数组排序,求前缀和。
#include<bits/stdc++.h>
using namespace std;
int a[200005],b[200005],c[200005];
int main(){
//freopen("text.txt","r",stdin);
int n,k;
cin>>n>>k;
int u=0,v=0,w=0;
for(int i=1;i<=n;i++){
int x,y,z;
cin>>x>>y>>z;
if(y==1&&z==1)c[u++]=x;
else if(y==1)a[v++]=x;
else if(z==1)b[w++]=x;
}
sort(a,a+v);
sort(b,b+w);
for(int i=0;i<min(v,w);i++){
c[u++]=a[i]+b[i];
}
if(u<k){
cout<<-1;
return 0;
}
sort(c,c+u);
int sum=0;
for(int i=0;i<k;i++)sum+=c[i];
cout<<sum;
return 0;
}
总结
文件输入:freopen("text.in","r",stdin);
文件输出:freopen("text.out","w",stdout);