zoukankan      html  css  js  c++  java
  • codeforces 1408D. Searchlights (暴力 + 前缀优化)

    题目链接:https://codeforces.com/problemset/problem/1408/D

    要让所有的罪犯逃离,必须满足对于每一对罪犯和探照灯 ((i,j)) : 要么 (a[i] > c[j]), 要么 (b[i] > d[j])

    所以对于 ((i,j)), 处理出罪犯 (i) 逃离信号灯 (j),所需要向上移动 (x) 步,或向右移动 (y) 步的对 ((x,y)).(如果罪犯 (i) 本来就不会被探照灯 (j) 照到,则跳过)

    所有罪犯都成功逃离,即所有 ((x,y)) 对都被满足

    处理好后,将所有 ((x,y)) 对按横坐标 (x) 排序,然后枚举所有罪犯向上移动的距离 (i), 对于所有 (x <= i) 的对,已经被满足了,而所有 (x > i) 的对,则只能通过向右移动来满足,也即找出剩余对中最大的 (y), 这个可以用后缀最大值来优化到 (O(1))

    所以复杂度即为 (O(nm + 1e6))

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 2010;
    
    int n, m, tot = 0;
    
    int a[maxn], b[maxn], c[maxn], d[maxn], mx[maxn * maxn];
    
    struct Node{
    	int x, y;
    	
    	bool operator < (const Node &t) const{
    		return x < t.x;
    	}
    }node[maxn * 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 = s * 10 + ch - '0'; ch = getchar(); } return s * f; }
    
    int main(){
    	n = read(), m = read();
    	for(int i = 1 ; i <= n ; ++i) a[i] = read(), b[i] = read();
    	for(int i = 1 ; i <= m ; ++i) c[i] = read(), d[i] = read();
    	
    	// n * m 个条件都要满足 
    	for(int i = 1 ; i <= n ; ++i){
    		for(int j = 1 ; j <= m ; ++j){
    			if(a[i] <= c[j] && b[i] <= d[j]) {
    				node[++tot].x = c[j] - a[i] + 1;
    				node[tot].y = d[j] - b[i] + 1;
    			}
    		}
    	}
    	
    	sort(node + 1, node + 1 + tot);	
    	
    	for(int i = tot ; i >= 0 ; --i){
    		mx[i] = max(mx[i + 1], node[i].y); 
    	}
    	
    //	printf("node:
    ");
    //	for(int i = 1 ; i <= tot ; ++i) printf("%d %d
    ", node[i].x, node[i].y); printf("
    ");
    //	for(int i = 1 ; i <= tot ; ++i) printf("%d ", mx[i]); printf("
    ");
    	
    	int ans = 1000000007;
    	int j = 0;
    	for(int i = 0 ; i <= 1000001 ; ++i){
    		while(node[j + 1].x <= i && j < tot) ++j;
    //		printf("%d %d
    ", i, j);
    		ans = min(ans, i + mx[j + 1]);
    	}
    	
    	printf("%d
    ", ans);
    	
    	return 0;
    }
    
  • 相关阅读:
    Quartz入门例子简介 从入门到菜鸟(一)
    初识Quartz之第一个Quartz实例
    @DisallowConcurrentExecution 注解的作用 【定时器执行完当前任务才开启下一个线程的方式】
    no identities are available for signing
    Unity3D研究院之在把代码混淆过的游戏返混淆回来
    安沃广告问题
    IOS 接ShareSDK问题
    网页中插入Flvplayer视频播放器代码
    unity Android 打包后读取 xml 文件
    unity3d 下操作excel 与打印
  • 原文地址:https://www.cnblogs.com/tuchen/p/14090906.html
Copyright © 2011-2022 走看看