• GYM 102452E 题解


    Codeforces

    Description.

    给定一个排列,每次可以选出 \(3\) 个数并删掉最大和最小的。
    问哪些数能存活到最后。

    Solution.

    首先考虑那个中为数经典套路,大于它的 \(+1\) 小于它的 \(-1\)
    首先,考虑如果序列和为 \(0\) 那肯定可以。
    就考虑肯定有相连三个位置存在 \(+1\)\(-1\),那操作这三个位置,然后就规约成子问题。
    那我们需要减少 \(+1\)\(-1\) 的数量。
    发现连着的三个 \(+1\)\(-1\) 可以减少两个,而且这是唯一方法。
    所以直接扫一遍,每次如果遇到一个需要消的 \(tp\leftarrow tp+1\),如果遇到一个敌人就 \(tp\leftarrow tp-1\) (可以用两个同伴去牺牲掉换掉。
    遇到当前为 \(0\) 的那个数直接全部清空,因为不能跨过它进行操作,它必须留到最后。
    然后就做完了。

    Coding.

    点击查看不行代码
    //是啊,你就是那只鬼了,所以被你碰到以后,就轮到我变成鬼了{{{
    #include<bits/stdc++.h>
    using namespace std;typedef long long ll;
    template<typename T>inline void read(T &x)
    {
    	x=0;char c=getchar(),f=0;
    	for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
    	for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    	f?x=-x:x;
    }
    template<typename T,typename...L>inline void read(T &x,L&...ln) {read(x),read(ln...);}/*}}}*/
    int n,a[10005],fg[10005];
    inline int sign(int x) {return x<0?-1:x>0?1:0;}
    inline void solve()
    {
    	read(n);for(int i=1;i<=n;i++) read(a[i]);
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=1;j<=n;j++) fg[j]=sign(a[j]-a[i]);
    		int sm=0,tp=0;for(int j=1;j<=n;j++) sm+=fg[j];
    		int sig=sign(sm);for(int j=1;j<=n;j++)
    		{
    			if(fg[j]==0) tp=0;else if(fg[j]!=sig) tp=max(tp-1,0);else tp++;
    			if(tp>=3) {sm-=2*sig,tp-=2;if(!sm) break;}
    		}
    		//putchar('\n');for(int j=1;j<=n;j++) printf("%d%c",fg[j],j==n?'\n':' ');
    		if(sm) putchar('0');else putchar('1');
    	}putchar('\n');
    }
    int main() {int Ca;for(read(Ca);Ca--;) solve();return 0;}
    
  • 相关阅读:
    opencv学习笔记7 重映射和仿射变换
    opencv学习笔记8 高斯金字塔,拉普拉斯金字塔,调整大小
    opencv学习笔记6 角点检测
    opencv学习笔记5 霍夫变换 漫水填充
    opencv学习笔记4 边缘检测
    opencv学习笔记3 滤波 形态学
    opencv学习笔记2 拖动条,亮度对比度 颜色空间缩减 鼠标事件
    opencv学习笔记1 加载图像 图像融合 分通道与合并
    URL编码表
    BUUCTF-[GWCTF 2019]我有一个数据库 1
  • 原文地址:https://www.cnblogs.com/pealfrog/p/15367194.html
Copyright © 2020-2023  润新知