• [LuoguP1034][Noip2002] 矩形覆盖


    [LuoguP1034][Noip2002] 矩形覆盖(Link

    在平面上有(N)个点,(N)不超过五十, 要求将这(N)个点用(K)个矩形覆盖,(k)不超过(4),要求最小化矩形之和。

    其实这个题应该是十分的简单,因为2002年蓝题的难度可想而知,一般都是思路简单码量大的题。这个题思路也就是十分暴力的枚举每一个点所属的矩阵的编号,然后题目要求所有的矩形不能重叠,于是就有了一个(Judge)函数,最后最小化矩形面积和就可以了。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std ;
    typedef long long LL ;
    const int MAXN = 51 ;
    const int MAXM = 51 ;
    const int Inf = 1e6  ;
    int N, K, Ans = Inf, P ;
    struct NODE {int X, Y ;} E[MAXN] ;
    struct SQUR {int X[MAXN][3], Y[MAXN][3], V[MAXN] ; } Sq[5] ;
    
    inline int maxx(int pos,int cos){if(pos>cos)return pos;else return cos;} 
    inline int minn(int pos,int cos){if(pos>cos)return cos;else return pos;}
    
    inline int Read() {
        int X = 0, F = 1 ; char ch = getchar() ;
        while (ch > '9' || ch < '0') F = (ch == '-' ? - 1 : 1), ch = getchar() ;
        while (ch >= '0' && ch <= '9') X=(X<<1)+(X<<3)+(ch^48), ch = getchar() ;
        return X * F ;
    }
    
    inline int Judge(int Now, int To) {
    	int X[3], Y[3] ; X[1] = Y[1] = Inf, X[2] = Y[2] = - Inf ;
    	X[1] = min(Sq[To].X[Now - 1][1], E[Now].X) ;
    	X[2] = max(Sq[To].X[Now - 1][2], E[Now].X) ;
    	Y[1] = min(Sq[To].Y[Now - 1][1], E[Now].Y) ;
    	Y[2] = max(Sq[To].Y[Now - 1][2], E[Now].Y) ;
    	for (int i = 1 ; i <= K ; i ++) if (i != To) {
    		for (int k = 1 ; k <= 2 ; k ++) {
    			Sq[i].X[Now][k] = Sq[i].X[Now - 1][k] ;
    			Sq[i].Y[Now][k] = Sq[i].Y[Now - 1][k] ;
    			Sq[i].V[Now] = Sq[i].V[Now - 1] ;
    			for (int j = 1 ; j <= 2 ; j ++) {
    				if (Sq[i].X[Now - 1][1] <= X[k] && Sq[i].X[Now - 1][2] >= X[k])
    				if (Sq[i].Y[Now - 1][1] <= Y[j] && Sq[i].Y[Now - 1][2] >= Y[j])
    					return Inf ;
    			}
    		}		
    	}
    	Sq[To].X[Now][1] = X[1] ; Sq[To].X[Now][2] = X[2] ;
    	Sq[To].Y[Now][1] = Y[1] ; Sq[To].Y[Now][2] = Y[2] ;
    	Sq[To].V[Now] = (X[2] - X[1]) * (Y[2] - Y[1]) ;
    	return P = Sq[To].V[Now] - Sq[To].V[Now - 1] ;
    }
    
    inline void Dfs(int Now, int Sum) {
    	if (Now == N + 1)
    		Ans = Sum ;
    	else for (int i = 1 ; i <= K ; i ++)
    		if (Sum + Judge(Now, i) < Ans)
    			Dfs(Now + 1, Sum + P) ;
    }
    
    int main() {
    	N = Read(), K = Read() ;
    	for (int i = 1 ; i <= N ; i ++) E[i].X = Read(), E[i].Y = Read() ;
    	for (int i = 1 ; i <= 4 ; i ++)
    		Sq[i].X[0][1] = Sq[i].Y[0][1] = Inf, 
    		Sq[i].X[0][2] = Sq[i].Y[0][2] = - Inf ;
    	Dfs(1, 0) ; 
    	printf("%d", Ans) ; 
    	return 0 ;
    }
    
  • 相关阅读:
    ubuntu安装docker-compose
    docker-compose常用命令(持续更新...)
    docker运行jpress
    gcc -o选项:指定输出文件
    gcc -c:只编译不链接,仅生成目标文件
    WMWare下安装centOS7,并使用xshell进行连接记录.
    主线程和子线程多种情况小探讨
    Sleep的本质
    为什么要对多线程进行加锁操作呢
    list操作相关总结
  • 原文地址:https://www.cnblogs.com/sue_shallow/p/P1037.html
Copyright © 2020-2023  润新知