zoukankan      html  css  js  c++  java
  • 洛谷 P4753 River Jumping(贪心)

    传送门


    解题思路

    首先考虑无解的情况:

    1. 首尾距离 \(<s\)
    2. 第一个石头到 \(0\) 的距离 \(<s\) 或第二个石头到 \(n+1\) 的距离 \(<s\)
    3. 存在一个 \(a[i+1]-a[i-1]<s\)

    判断完无解的情况,考虑构造答案。

    最简单的方法是过去的时候跳1,3,5,7,9,……,m,m+1,回来的时候跳m-1,m-3,……,4,2,0。

    性质3保证了这一构造是正确的。

    注意方案要分m的奇偶(卡了我一晚上)。

    AC代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    #include<bitset>
    #include<stack>
    using namespace std;
    template<class T>inline void read(T &x)
    {
        x=0;register char c=getchar();register bool f=0;
        while(!isdigit(c))f^=c=='-',c=getchar();
        while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
        if(f)x=-x;
    }
    template<class T>inline void print(T x)
    {
        if(x<0)putchar('-'),x=-x;
        if(x>9)print(x/10);
        putchar('0'+x%10);
    }
    const int maxn=100005;
    int n,m;
    long long a[maxn],s; 
    int main(){
    	ios::sync_with_stdio(false);
    	cin>>n>>m>>s;
    	for(int i=1;i<=m;i++) cin>>a[i];
    	if(m==0&&n<s){
    		cout<<"NO";
    		return 0;
    	}
    	if(m!=0&&(a[1]<s||n-a[m]<s)){
    		cout<<"NO";
    		return 0;
    	}
    	for(int i=2;i<m;i++){
    		if(a[i+1]-a[i-1]<s){
    			cout<<"NO";
    			return 0;
    		}
    	}
    	cout<<"YES"<<endl;
    	int i=0;
    	for(i=1;i<=m;i+=2) cout<<i<<" ";
    	cout<<m+1<<' ';
    	i-=2;
    	if(i==m) i--;
    	else i=m;
    	for(;i>=1;i-=2) cout<<i<<' ';
    	cout<<0;
    	return 0;
    }
    
  • 相关阅读:
    JS: 子项可以来回交换的两个下拉列表
    DOM事件
    DOM基础2——元素
    DOM基础1
    JS: 随机点名程序与万年历
    G_S男女匹配算法(算法的第一个程序2016.09.19)
    Java IO流详尽解析(大神之作)
    细讲解JAVA中的IO流
    c++运算符的优先级(收好不谢)
    java程序——输出当月日历表
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/15527172.html
Copyright © 2011-2022 走看看