• 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;
    }
    
  • 相关阅读:
    A*算法的原理 <转>
    Unity性能优化之 Draw Call原理<转>
    关于XML中:XmlNode和XmlElement的涵义及不同之处
    MySql 数据库连接池
    代码中批量执行Oracle SQL语句
    科密指纹考勤机B329采集
    VB网络编程(webbrowser+Inet+抓包封包+经验)
    Lambda表达式
    网络编程
    多线程
  • 原文地址:https://www.cnblogs.com/tuchen/p/14090906.html
Copyright © 2020-2023  润新知