zoukankan      html  css  js  c++  java
  • codeforces 1428 D. Bouncing Boomerangs (贪心)

    题目链接:https://codeforces.com/contest/1428/problem/D


    首先发现贪心策略: 对于当前列 1. 如果路径有一个动物,意味着这个列上有一个动物,那尽量向上放一定是最优的 2. 若路径上有两个动物,意味着除了这个列上有一个动物,该行也需要有一个动物,
    则需要从之后的列找到路径上只有一个动物的列进行占领 3. 若路径上有三个动物,则需要对后面相离最近的可占领的列进行占领
    具体实现细节看代码 需要一点码力 ```c++ #include #include #include #include #include #include #include using namespace std; typedef long long ll;

    const int maxn = 200010;

    int n,cnt,flag;
    int a[maxn],oc[maxn],fr[maxn],ty[maxn];
    int x[maxn],y[maxn],pos[maxn],p2[maxn];

    ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s10+ch-'0'; ch=getchar(); } return sf; }

    int main(){
    cnt = 0, flag = 0;
    memset(oc,0,sizeof(oc));
    n = read();
    for(int i=1;i<=n;++i) a[i] = read();

    for(int i=n-1;i>=1;--i){
    	if(a[i+1] == 1) pos[i] = i+1;
    	else{
    		pos[i] = pos[i+1];
    	}
    }
    
    for(int i=n-1;i>=1;--i){
    	if(a[i+1]!=0) p2[i] = i+1;
    	else{
    		p2[i] = p2[i+1];
    	}
    }
    

    // for(int i=1;i<=n;++i) printf("%d ",pos[i]); printf(" ");

    for(int i=1;i<=n;++i){
    	if(!a[i]) continue; 
    	if(!oc[i]){ // 路径没被占领
    		if(a[i] == 1){
    			fr[i] = i;
    			++cnt;
    			x[cnt] = fr[i], y[cnt] = i;
    		}
    		if(a[i] == 2){
    			fr[i] = i;
    			++cnt;
    			x[cnt] = fr[i], y[cnt] = i;
    			int p = pos[i];
    			while(oc[p]) p = pos[p]; // 向后找能放置的位置 (只有 a[i] = 1 的位置能放置) 
    			if(!p){
    				flag = 1; // 找不到这个位置 
    				break; 
    			} 
    			oc[p] = i; ty[p] = 2;
    			
    		}
    		if(a[i] == 3){
    			fr[i] = i;
    			++cnt;
    			x[cnt] = fr[i], y[cnt] = i;
    			int p = p2[i];
    			while(oc[p]) p = p2[p]; // 向后找能放置的位置 (a[i] = 1, a[i] = 2 的位置都能放置) 
    			if(!p){
    				flag = 1; // 找不到这个位置 
    				break; 
    			} 
    			oc[p] = i; ty[p] = 3; // 位置被占领 2 个 
    			
    		}
    	}else{
    		if(a[i]==1){
    			if(ty[i] == 2){
    				fr[i] = oc[i];
    				++cnt;
    				x[cnt] = fr[i], y[cnt] = i;	
    			}
    			if(ty[i] == 3){
    				fr[i] = oc[i];
    				++cnt;
    				x[cnt] = fr[i], y[cnt] = i;
    				if(fr[i] + 1 <= n){
    					++cnt;
    					x[cnt] = fr[i] + 1, y[cnt] = i;
    				}else{
    					flag = 1;
    					break;
    				}
    			}
    		} 
    		
    		if(a[i] == 2){
    			fr[i] = oc[i];
    			++cnt;
    			x[cnt] = fr[i], y[cnt] = i;
    			if(fr[i] + 1 <= n){
    				++cnt;
    				x[cnt] = fr[i] + 1, y[cnt] = i;
    			}else{
    				flag = 1;
    				break;
    			}
    			
    			int p = pos[i];
    			while(oc[p]) p = pos[p]; // 向后找能放置的位置 (只有 a[i] = 1 的位置能放置) 
    			if(!p){
    				flag = 1; // 找不到这个位置 
    				break; 
    			} 
    			oc[p] = fr[i] + 1; ty[p] = 2;
    		} 
    		
    		if(a[i] == 3){
    			fr[i] = oc[i];
    			++cnt;
    			x[cnt] = fr[i], y[cnt] = i;
    			
    			if(fr[i] + 1 <= n){
    				++cnt;
    				x[cnt] = fr[i] + 1, y[cnt] = i;
    			}else{
    				flag = 1;
    				break;
    			}
    			
    			
    			int p = p2[i];
    			while(oc[p]) p = p2[p]; // 向后找能放置的位置 (a[i] = 1, a[i] = 2 的位置都能放置) 
    			if(!p){
    				flag = 1; // 找不到这个位置 
    				break; 
    			}
    			oc[p] = fr[i] + 1; ty[p] = 3; // 位置被占领 2 个 
    			
    		}
    	}
    }
    
    if(flag){
    	printf("-1
    ");
    }
    else{
    	printf("%d
    ",cnt);
    	for(int i=1;i<=cnt;++i){
    		printf("%d %d
    ",x[i],y[i]);
    	}
    }
    
    return 0;
    

    }

  • 相关阅读:
    关于vue中如何实现排到他思想
    js 文件下载
    js文件上传
    webpack学习笔记
    this总结
    React中props与state
    js事件总结
    js深拷贝与浅拷贝
    JS设计模式之观察者模式
    ES5与ES6的继承
  • 原文地址:https://www.cnblogs.com/tuchen/p/13842856.html
Copyright © 2011-2022 走看看