zoukankan      html  css  js  c++  java
  • CSP-S 2020 T4贪吃蛇

    题目大意

    题解

    这题考场上一看就感觉很可做,非常快就想到了简单又自然的70分方法,但是将大量的时间都放在了想办法优化到满分上,导致T3都没时间想。

    做法不难,容易发现,如果当前的(Max)吃掉(Min)以后不是最小的,那么一定可以吃,因为下一个吃完以后一定会比他小,也就是会先被吃掉,所以只需要把问题交给下一条蛇就行了。

    然后可以发现,如果当前吃完以后变成最小的了,那么就要看下一个会不会选择吃掉它,而下一个又要再需要继续看接下来的蛇的操作。

    容易总结出一条结论,当现在吃完以后变成最小的以后,只需要判断第一个吃完不是最小的蛇与当前轮数的奇偶性就行了。

    然后接下来的问题就比较简单了,可以用两个队列来维护。一个队列维护还未被操作的蛇,一个队列维护已经操作后的蛇,两个队列都是单调的,就可以以此来维护(Max)(Min)了。

    当只剩两条蛇的时候要特判,此时显然是可以吃的。

    代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define N 3000010
    using namespace std;
    int T,n,i,k,x,y,ans,l,r,l1,r1;
    struct node{
    	int val,id;
    }lp[N],a[N],p[N];
    inline int read(){
    	int x=0;
    	char ch=getchar();
    	while (ch<'0'||ch>'9') ch=getchar();
    	while (ch>='0'&&ch<='9'){
    		x=(x<<1)+(x<<3)+(ch^48);
    		ch=getchar();
    	}
    	return x;
    }
    int cmp(node x,node y){
    	if (x.val!=y.val) return x.val>y.val;
    	return x.id>y.id;
    }
    node getmax(){
    	if (l>r) return p[l1++];
    	if (l1>r1) return a[l++];
    	if (cmp(a[l],p[l1])) return a[l++];
    	else return p[l1++];
    }
    node getmin(){
    	if (l>r) return p[r1--];
    	if (l1>r1) return a[r--];
    	if (cmp(a[r],p[r1])==0) return a[r--];
    	else return p[r1--];
    }
    node getmin2(){
    	if (l>r) return p[r1];
    	if (l1>r1) return a[r];
    	if (cmp(a[r],p[r1])==0) return a[r];
    	else return p[r1];
    }
    void solve(){
    	l=1,r=n,l1=1,r1=0;
    	int tot;
    	node Max,Min;
    	ans=n;
    	while (true){
    		if (ans<=2){
    			ans=1;
    			return;
    		}
    		Max=getmax();
    		Min=getmin();
    		Max.val-=Min.val;
    		if (cmp(Max,getmin2())==0){
    			tot=1;
    			p[++r1]=Max;
    			while (true){
    				if (ans-tot<=2) {
    					tot++;
    					if (tot%2==1) ans--;
    					return;
    				}
    				Max=getmax();
    				Min=getmin();
    				Max.val-=Min.val;
    				tot++;
    				if (cmp(Max,getmin2())){
    					if (tot%2==1) ans--;
    					return;
    				}
    				else
    					p[++r1]=Max;
    			}
    		}
    		else{
    			ans--;
    			p[++r1]=Max;
    		}
    	}
    }
    int main(){
    	freopen("snakes.in","r",stdin);
    	freopen("snakes.out","w",stdout);
    	T=read();
    	n=read();
    	for (i=1;i<=n;i++) lp[i].val=read(),lp[i].id=i;
    	for (i=1;i<=n/2;i++) swap(lp[i],lp[n-i+1]);
    	for (i=1;i<=n;i++) a[i]=lp[i];
    	solve();
    	printf("%d
    ",ans);
    	T--;
    	while (T--){
    		k=read();
    		for (i=1;i<=k;i++) x=read(),y=read(),lp[n-x+1].val=y;
    		for (i=1;i<=n;i++) a[i]=lp[i];
    		solve();
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    vim讲解
    tar常用解包
    linux扩展权限
    为Virtualbox中的Solaris10安装VBoxAdditions
    Solaris10下Telnet、SSH、ftp使用root登录
    linux软链接和硬链接
    curl命令学习(转载的)
    linux磁盘分区fdisk命令详解
    在服务器上排除问题的头五分钟
    Java对文件压缩/加密/解密/解压缩的例子,DES/RSA
  • 原文地址:https://www.cnblogs.com/Mohogany/p/13965774.html
Copyright © 2011-2022 走看看