zoukankan      html  css  js  c++  java
  • poj1328解题报告(贪心、线段交集)

     

    POJ 1328,题目链接http://poj.org/problem?id=1328

    题意:

    有一海岸线(x),一半是陆地(y<0)、一半是海(y>0),海上有一些小岛(用坐标点表示P1P2...),现要在海岸线上建雷达(覆盖半径R)。给出所有小岛的位置,和雷达半径,求最少需要多少个雷达?

     

    思路:

    1. 知道小岛位置,和雷达半径,那么以小岛为圆心,雷达覆盖半径为半径画圆,可以求出小岛与x轴有0(雷达无法覆盖)、1(雷达只能在这个点上才能覆盖)、2个交点(雷达在两点之间都能覆盖该小岛)

    2. 要求最少雷达多少个,即把雷达放在1中线段的交集内。

    那么这就变成了线段交集问题。(贪心)

    代码:

    //404k 79ms
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    
    typedef struct tagLINE{
    	double left;
    	double right;
    }Line;
    void sortLineBuf(Line *p, int num)
    {
    	Line temp;
    	for (int i=0; i<num; ++i)
    	{
    		for (int j=i+1; j<num; ++j)
    		{
    			if (p[j].left < p[i].left){
    				temp = p[i];
    				p[i] = p[j];
    				p[j] = temp;
    			}
    		}
    	}
    }
    int main()
    {
    	int caseNum = 0;
    	double tempPoint;
    	Line tempLine;
    	while (true)
    	{
    		int islandNum = 0, r = 0;
    		scanf("%d%d", &islandNum, &r);
    		if (islandNum == 0 && r == 0) break;
    
    		double *p = (double*)malloc(sizeof(double) * islandNum * 2);
    		double *pX = p;
    		double *pY = p+islandNum;
    		for(int i=0; i<islandNum; ++i){
    			scanf("%lf%lf", &pX[i], &pY[i]);
    		}
    		//
    		int rapar = 0;
    		bool bImpossible = true;
    		Line* pLine = (Line*)malloc(sizeof(Line) * islandNum);
    		//1 转换为直线
    		for(int i=0; i<islandNum; ++i){
    			if (fabs(pY[i]) > r){
    				bImpossible = false;
    				rapar = -1;
    				break;
    			}
    			tempPoint = sqrt(r*r - pY[i]*pY[i]);
    			pLine[i].left = pX[i]-tempPoint;
    			pLine[i].right = pX[i]+tempPoint;
    		}
    		if (bImpossible)
    		{
    			rapar = 1;
    			//2
    			sortLineBuf(pLine, islandNum);
    			//3 求解线段交集
    			tempLine = pLine[0];
    			for (int i=1; i<islandNum; ++i)  
    			{  
    				if (pLine[i].left > tempLine.right)  
    				{  
    					++rapar; 
    					tempLine = pLine[i];
    				}  
    				else if (pLine[i].right < tempLine.right)  
    				{  
    					tempLine = pLine[i];  
    				}  
    			} 
    		}
    		printf("Case %d: %d
    ", ++caseNum, rapar);
    		free(p);
    		free(pLine);
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    填充与复制
    张量排序
    数据统计
    合并与分割
    前向传播(张量)- 实战
    数学运算
    Broadcasting
    TensorFlow2-维度变换
    集合3
    集合2
  • 原文地址:https://www.cnblogs.com/songcf/p/3763650.html
Copyright © 2011-2022 走看看