Codeforces Round #649 (Div. 2) 参与排名人数11286
[codeforces 1364B] Most socially-distanced subsequence 绝对值脱壳的4种形态
总目录详见https://blog.csdn.net/mrcrack/article/details/103564004
在线测评地址https://codeforces.com/contest/1364/problem/B
Problem | Lang | Verdict | Time | Memory |
---|---|---|---|---|
B - Most socially-distanced subsequence | GNU C++17 | Accepted | 46 ms | 800 KB |
题目大意:给定数组a,可以删除任意元素,要求剩下的元素,相邻差值绝对值和最大,对应的剩下元素的个数最少,输出最少个数。
|x-y|+|y-z|
1.|x-y|脱壳情况如下
x>=y,|x-y|=x-y
x<=y,|x-y|=y-x
2.|y-z|脱壳情况如下
y>=z,|y-z|=y-z
y<=z,|y-z|=z-y
3.|x-y|+|y-z|脱壳情况如下
有4种组合
x>=y,y>=z
|x-y|+|y-z|=x-y+y-z=x-z此种情况,可删除元素y
x>=y,y<=z
|x-y|+|y-z|=x-y+z-y=x+z-2*y
x<=y,y>=z
|x-y|+|y-z|=y-x+y-z=2*y-(x+z)
x<=y,y<=z
|x-y|+|y-z|=y-x+z-y=z-x此种情况,可删除元素y
按上述思路,采用栈(在连续数据中,有目的的选取部分数据,用栈比较合适)的方式,编写的AC代码如下
#include
#define maxn 100010
int a[maxn],st[maxn],top;
void solve(){
int i,x,y,z,n;
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",&a[i]);
top=0;
for(i=1;i<=n;i++){
while(top>=2){
x=st[top-1],y=st[top],z=i;
if((a[x]>=a[y]&&a[y]>=a[z])||(a[x]<=a[y]&&a[y]<=a[z]))top--;
else break;
}
st[++top]=i;
}
printf("%d\n",top);
for(i=1;i<=top;i++)printf("%d ",a[st[i]]);
printf("\n");
}
int main(){
int t;
scanf("%d",&t);
while(t--)solve();
return 0;
}
按上述思路,采用再开一个数组用来存储剩下的数组元素,对应的AC代码,建议读者不用细读,只是告诉读者掌握数据结构有多么重要,懂和不懂,同一个思路,编出的代码差太多了。
Problem | Lang | Verdict | Time | Memory |
---|---|---|---|---|
B - Most socially-distanced subsequence | GNU C++17 | Accepted | 62 ms | 1900 KB |
#include
#define maxn 100010
int a[maxn],b[maxn],l[maxn],r[maxn],vis[maxn];
void solve(){
int n,i,x,y,z,ans,j;
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",&a[i]);
for(i=1;i<=n;i++)vis[i]=0;
if(n==2){
printf("2\n");
for(i=1;i<=n;i++)printf("%d ",a[i]);
printf("\n");
return ;
}
l[2]=1,y=2,r[2]=3,j=0;
while(y+1<=n){//n>=3
if((a[l[y]]>=a[y]&&a[y]>=a[r[y]])||(a[l[y]]<=a[y]&&a[y]<=a[r[y]])){
y++;
l[y]=l[y-1],r[y]=y+1;
if(!vis[l[y-1]])vis[l[y-1]]=1,b[++j]=a[l[y-1]];
}else{
if(!vis[l[y]])vis[l[y]]=1,b[++j]=a[l[y]];
if(!vis[y])vis[y]=1,b[++j]=a[y];
y++,l[y]=y-1,r[y]=y+1;;
}
}
b[++j]=a[y];
printf("%d\n",j);
for(i=1;i<=j;i++)printf("%d ",b[i]);
printf("\n");
}
int main(){
int t;
scanf("%d",&t);
while(t--)solve();
return 0;
}