zoukankan      html  css  js  c++  java
  • [CSP-S模拟测试]:Emotional Flutter(贪心)

    题目传送门(内部题51)


    输入格式

    第一行一个整数$t$表示数据组数。
    每组数据的第一行有三个整数$s,k,n$。
    第二行有$n$个整数$A_1,A_2,...,A_n$,依次表示黑白条的长度。


    输出格式

    若能通过输出$"TAK"$,否则输出$"NIE"$。


    样例

    样例输入:

    2
    2 8 7
    2 5 6 3 2 1 2
    2 8 4
    1 6 7 4

    样例输出:

    TAK
    NIE


    数据范围与提示

    样例解释:

    数据范围:

    $30\%$的数据,$nleqslant 1300$;
    $50\%$的数据,$nleqslant 22,000$;
    $100\%$的数据,$2leqslant nleqslant 500,000,1leqslant s<kleqslant {10}^9,1leqslant A_ileqslant {10}^9,1leqslant tleqslant 10$。
    数据有梯度。输入文件较大请使用读入优化。


    题解

    其实就是一个贪心,主要是策略很难想。

    首先来处理脚的长度,我们可以将所有的黑块都延长$s$,所有的白块左端点向右移动$s$,这样就相当与忽略了脚的长度。

    然后会有一些特判的情况,对于我的贪心策略,我们只需要用到当一个黑块长度大于$k$时,肯定跳不过去,所以直接输出$"NIE"$即可。

    现在来讲对于一般情况,我是如何判断的。

    首先,将所有的黑块的左端点和右端点分别$mod k$,那么我们是不能在这段区间进行起跳的;如果出现$mod k$完之后右端点小于左端点,那么区间$[0,r]$和区间$[l,k-1]$是不能起跳的。

    之后我们只需要将所有的不能跳的区间排个序,然后我们只需要找到一个可以起跳的点即可。

    细节比较多,慢慢调吧……

    时间复杂度:$Theta(nlog n)$。

    期望得分:$100$分。

    实际得分:$100$分。


    代码时刻

    #include<bits/stdc++.h>
    using namespace std;
    struct rec{long long l,r;}e[10000000];
    long long s,k,n;
    long long sum[5000001];
    long long lft[5000001],rht[5000001],wsq;
    int top;
    bool flag;
    bool cmp(rec a,rec b){return a.l==b.l?a.r<b.r:a.l<b.l;}
    int main()
    {
    	int T;scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%lld%lld%lld",&s,&k,&n);
    		top=flag=wsq=0;
    		for(int i=1;i<=n;i++)
    		{
    			long long a;
    			scanf("%lld",&a);
    			if(i&1)a+=s;
    			else{a-=s;a%=k;}
    			if(a>k)flag=1;
    			sum[i]=sum[i-1]+a;
    			if(i&1)
    			{
    				lft[i]=sum[i-1]+1;
    				rht[i]=sum[i]-1;
    			}
    		}
    		if(((n&1)&&sum[n]<=k)||((!(n&1))&&sum[n-1]<=k)){puts("TAK");continue;}
    		if(flag){puts("NIE");continue;}
    		for(int i=1;i<=n;i+=2)
    		{
    			lft[0]=lft[i]%k;
    			rht[0]=rht[i]%k;
    			if(rht[0]<lft[0])
    			{
    				e[++top]=(rec){0,rht[0]};
    				e[++top]=(rec){lft[0],k-1};
    			}
    			else e[++top]=(rec){lft[0],rht[0]};
    		}
    		sort(e+1,e+top+1,cmp);
    		if(e[1].l){puts("TAK");goto nxt;}
    		for(int i=1;i<=top;i++)
    		{
    			if(wsq+1<e[i].l){puts("TAK");goto nxt;}
    			wsq=max(wsq,e[i].r);
    		}
    		if(wsq<k-1){puts("TAK");continue;}
    		puts("NIE");
    		nxt:;
    	}
    	return 0;
    }
    

    rp++

  • 相关阅读:
    mojo 接口示例
    MojoliciousLite: 实时的web框架 概述
    接口返回json
    centos 6.7 perl 版本 This is perl 5, version 22 安装DBI DBD
    centos 6.7 perl 5.22 安装DBD 需要使用老的perl版本
    商业智能改变汽车行业
    商业智能改变汽车行业
    读MBA经历回顾(上)目的决定手段——北漂18年(48)
    perl 升级到5.20版本
    Group Commit of Binary Log
  • 原文地址:https://www.cnblogs.com/wzc521/p/11569467.html
Copyright © 2011-2022 走看看