Codeforces Round 111 (Rated for Div. 2)简训
导语
日常
涉及的知识点
贪心,思维
链接:Codeforces Round 111 (Rated for Div. 2)
题目
A Find The Array
题目大意:定义一种序列a是美丽的: a i = 1 a_i=1 ai=1或者 a i − 1 a_i-1 ai−1和 a i − 2 a_i-2 ai−2至少一个也出现在序列中,给出一个数s,当序列和为s时,判断能满足美丽的最小序列长度是多少
思路:贪心即可,与其考虑 a i − 1 a_i-1 ai−1和 a i − 2 a_i-2 ai−2不如考虑 a i + 2 a_i+2 ai+2存在,详见代码
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5;
int t,s,sum[maxn];
int main() {
scanf("%d",&t);
for(int i=1; i<=80; i++)
sum[i]=i*i;
while(t--) {
scanf("%d",&s);
if(s==1) {//特判
printf("1\n");
continue;
}
int pos=lower_bound(sum+1,sum+81,s)-sum;
printf("%d\n",pos);
}
return 0;
}
B Maximum Cost Deletion
题目大意:略
思路:一开始想复杂了,其实就是去掉数量最少的0/1的连通长度,根据b的大小贪心的选择策略即可
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e3;
int t,n,a,b,num[maxn];
int main() {
scanf("%d",&t);
while(t--) {
int cnt[2]= {0};
scanf("%d%d%d",&n,&a,&b);
for(int i=1; i<=n; i++)scanf("%1d",&num[i]);
for(int i=1; i<n; i++)//统计连通块
if(num[i]!=num[i+1])cnt[num[i]]++;
cnt[num[n]]++;
if(b>=0)printf("%d\n",a*n+n*b);//贪心选择
else printf("%d\n",a*n+b*(min(cnt[0],cnt[1])+1));//使减去的b最少
}
return 0;
}
C Manhattan Subarrays
题目大意:略
思路:很容易就能推得,在i>j>k的情况下,只有ai<aj<ak和ai>aj>ak这两种情况会产生坏序列,当规模为5的时候必定能找到三个数满足前面这个条件,规模为4的时候可能不满足
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6;
int t,n,a[maxn];
bool judge(int x,int y,int z) {
return (x<=y&&y<=z)||(x>=y&&y>=z);
}
int main() {
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
int cnt=2*n-1;
for(int i=1; i<=n; i++)scanf("%d",&a[i]);
for(int i=1; i<=n-2; i++)
if(!judge(a[i],a[i+1],a[i+2])) {
cnt++;
if(i+3<=n&&(!judge(a[i],a[i+2],a[i+3]))&&(!judge(a[i],a[i+1],a[i+3]))&&(!judge(a[i+1],a[i+2],a[i+3])))cnt++;
}
printf("%d\n",cnt);
}
return 0;
}