uva 10084 Hotter Colder

Problem E: Hotter Colder

The children‘s game Hotter Colder is played as follows. Player A leaves the room while player B hides an object somewhere in the room. Player A re-enters at position (0,0) and then visits various other positions about the room. When player A visits a new position,
player B announces "Hotter" if this position is closer to the object than the previous position; player B announces "Colder" if it is farther and "Same" if it is the same distance.

Input consists of up to 50 lines, each containing an x,y coordinate pair followed by "Hotter", "Colder", or "Same". Each pair represents a position within the room, which may be assumed to be a square with opposite corners at (0,0) and (10,10). For each line
of input print a line giving the total area of the region in which the object may have been placed, to 2 decimal places. If there is no such region, output 0.00.

Sample Input

10.0 10.0 Colder

10.0 0.0 Hotter

0.0 0.0 Colder

10.0 10.0 Hotter

Output for Sample Input

50.00

37.50

12.50

0.00

题目大意:

有一个人玩游戏,起初是个左下角(0,0) 右上角(10,10)的矩形,有一个宝藏藏在这之间。这个人起初在(0,0) 每次走到一个点,会告诉你与原来的点相比距离宝藏近了还是远了,还是不变,根据这个每次求宝藏的范围(面积)。

解题思路:

每次相当于形成一个新的范围是凸包,只需要求这个凸包所有的点,然后按照极角排序,求面积。

这题wa了很多次,感觉代码略麻烦了一点点。

代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
using namespace std;

const double eps=1e-6;

struct point{
	double x,y;
	point(double x0=0,double y0=0){x=x0;y=y0;}
    double getdis(point p){
    	return double(sqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y)));
    }
    double xchen(point p){//this X P
        return x*p.y-p.x*y;
    }
    friend bool operator < (point a,point b){
		if(a.y!=b.y) return a.y<b.y;
		else return a.x<b.x;
	}
};

struct line{//line ax+by+c=0
	double a,b,c;
	line(double a0=0,double b0=0,double c0=0){a=a0;b=b0;c=c0;}
    void setline(point p1,point p2){
        a=p1.y-p2.y,b=p2.x-p1.x,c=p1.x*p2.y-p2.x*p1.y;
    }
    point getCrossPoint(line l1){//get the cross point of Line l1 and l2
        point tmp;
        tmp.x=(l1.b*c-b*l1.c)/(l1.a*b-l1.b*a);
        tmp.y=(l1.c*a-c*l1.a)/(l1.a*b-l1.b*a);
        return tmp;
    }
};

vector <point> p;

void ini(){
    p.clear();
    p.push_back(point(0,0));
    p.push_back(point(10,0));
    p.push_back(point(10,10));
    p.push_back(point(0,10));
}

line getLine(point p1,point p2){//get the Line that cross point p1 + p2/2
	line tmpLine;
	tmpLine.a=p2.x-p1.x;
	tmpLine.b=p2.y-p1.y;
	tmpLine.c=(p1.x*p1.x-p2.x*p2.x+p1.y*p1.y-p2.y*p2.y)/2.0;
	return tmpLine;
}

double xchen(point a,point b,point c){
	return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}

bool cmp(point a,point b){
	if(fabs(xchen(p[0],a,b))<eps) return a.getdis(p[0])<b.getdis(p[0]);
	else return xchen(p[0],a,b)>0;
}

void deal(point s,point d,int flag){
    line l2=getLine(s,d);
    vector <point> v;
    for(int i=0;i<p.size();i++){
        if(flag<0){
            if(p[i].getdis(s)<p[i].getdis(d)){
                v.push_back(p[i]);
            }
        }else{
            if(p[i].getdis(s)>p[i].getdis(d)){
                v.push_back(p[i]);
            }
        }
    }
    p.push_back(p[0]);
    for(int i=1;i<p.size();i++){
        line l1;
        l1.setline(p[i-1],p[i]);
        if( fabs(l1.a*l2.b-l1.b*l2.a)<eps ) continue;
        point tmp=l2.getCrossPoint(l1);
        if( fabs( fabs(tmp.x-p[i-1].x)+fabs(tmp.x-p[i].x)-fabs(p[i].x-p[i-1].x) ) > eps  ) continue;
        if( fabs( fabs(tmp.y-p[i-1].y)+fabs(tmp.y-p[i].y)-fabs(p[i].y-p[i-1].y) ) > eps  ) continue;
        v.push_back(tmp);
    }
    p.clear();
    sort(v.begin(),v.end());
    for(int i=0;i<v.size();i++){
        if(p.size()>0 && ( fabs(p.back().x-v[i].x)<eps &&  fabs(p.back().y-v[i].y)<eps ) ) continue;
        p.push_back(v[i]);
    }
	if(p.size()>=1) sort(++p.begin(),p.end(),cmp);
}

double getarea(){
    double sum=0;
    for(int i=1;i<p.size()-1;i++){
        point p1=point(p[i].x-p[0].x,p[i].y-p[0].y);
        point p2=point(p[i+1].x-p[0].x,p[i+1].y-p[0].y);
        sum+=fabs(p2.xchen(p1))/2.0;
    }
    return sum;
}

void solve(){
    string str;
    point s(0,0),d;
    double area=getarea();
    while(cin>>d.x>>d.y>>str){
        //if(d.x<-eps || d.y<-eps || d.x>10+eps || d.y>10+eps){
            //printf("0.00\n");
            //break;
        //}
        if(str=="Colder"){
            if(fabs(d.x-s.x)>eps || fabs(d.y-s.y)>eps){
                deal(s,d,-1);
                area=getarea();
            }
        }
        else if(str=="Hotter"){
            if(fabs(d.x-s.x)>eps || fabs(d.y-s.y)>eps){
                deal(s,d,1);
                area=getarea();
            }
        }
        else{
            area=0;
        }
        printf("%.2lf\n",area);
        if(area<eps) break;
        s=d;
    }
    while(cin>>d.x>>d.y>>str){
        printf("0.00\n");
        continue;
    }
}

int main(){
    ini();
    solve();
    return 0;
}

uva 10084 Hotter Colder,码迷,mamicode.com

时间: 2024-08-29 12:10:22

uva 10084 Hotter Colder的相关文章

POJ 2540 Hotter Colder --半平面交

题意: 一个(0,0)到(10,10)的矩形,目标点不定,从(0,0)开始走,如果走到新一点是"Hotter",那么意思是离目标点近了,如果是"Colder“,那么就是远了,"Same"是相同.要你推测目标点的可能位置的面积. 解法:半平面交水题.从一个点到另一个点远了,说明目标点在两点之间连线的中垂线的离源点较近的一侧,即我们每次都可以得到一条直线来切割平面,要么切割左侧,要么切割右侧,要么都切,再求一个半平面交就可以得出可能面积了. 代码: #incl

uva 10084

题意:在一个矩形空间内,左下角坐标(0,0),右上角坐标(10,10),然后两个小孩子玩游戏,乙让甲猜一个物体的位置,初始必须猜(0,0),然后之后甲说出的位置,乙都会根据上一次猜的位置和这一次猜的位置距离正确位置的远近给出一个答案,Colder说明这次猜远了,Hotter说明猜近了,Same说明猜的是正确位置.输出每次询问后,所有可能位置占的总面积. 题解:用切割多边形的方式求半平面交多边形面积.当前的点和之前的点的中点找到,然后之前点到当前点的有向连线逆时针旋转90°得到切割向量,中点加切割

POJ 2540 Hotter Colder

http://poj.org/problem?id=2540 题意:给你每次行走的路径,而且告诉你每次离一个点光源是远了还是近了,要求每次光源可能存在的位置的面积. 思路:如果出现"same",说明光源在中垂线上,面积为0,否则我们考虑远了或者近了,实际上就是在路径中两点连成直线的中垂线就是半平面直线,近了在这条直线的远侧,远了在这条直线的近侧. 1 #include<cstdio> 2 #include<iostream> 3 #include<cmat

poj 2540 Hotter Colder(极角计算半平面交)

题意:玩家A初始时在(0,0)位置,每移动一次,玩家B提示与目标位置的距离远了.近了还是不变:在B回答后,确定目标位置可能存在的区域面积: 思路:以玩家A上一个位置与当前位置的连线做中垂线,将目标位置代入中垂线方程,得到对应不等式,根据回答的类型增加相应的半平面: 每回合后对当前半平面求交,输出交的面积: #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #incl

计划,,留

下面给出的题目共计560道,去掉重复的也有近500题,作为ACMer Training Step1,用1年到1年半年时间完成.打牢基础,厚积薄发. 一.UVaOJ http://uva.onlinejudge.org 西班牙Valladolid大学的程序在线评测系统,是历史最悠久.最著名的OJ. 一.<算法竞赛入门经典> 刘汝佳 (UVaOJ 351道题) 以下部分内容摘自:http://sdkdacm.5d6d.com/thread-6-1-1.html "AOAPC I"

算法竞赛入门经典+挑战编程+USACO

下面给出的题目共计560道,去掉重复的也有近500题,作为ACMer Training Step1,用1年到1年半年时间完成.打牢基础,厚积薄发.   一.UVaOJ http://uva.onlinejudge.org  西班牙Valladolid大学的程序在线评测系统,是历史最悠久.最著名的OJ.   二.<算法竞赛入门经典> 刘汝佳  (UVaOJ  351道题)  以下部分内容摘自:http://sdkdacm.5d6d.com/thread-6-1-1.html   "AO

(Step1-500题)UVaOJ+算法竞赛入门经典+挑战编程+USACO

下面给出的题目共计560道,去掉重复的也有近500题,作为ACMer Training Step1,用1年到1年半年时间完成.打牢基础,厚积薄发. 一.UVaOJ http://uva.onlinejudge.org 西班牙Valladolid大学的程序在线评测系统,是历史最悠久.最著名的OJ. 二.<算法竞赛入门经典> 刘汝佳  (UVaOJ  351道题)  以下部分内容摘自:http://sdkdacm.5d6d.com/thread-6-1-1.html “AOAPC I”是刘汝佳(大

POJ2540-Hotter Colder(半平面交)

Hotter Colder Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2523   Accepted: 1045 Description The children's game Hotter Colder is played as follows. Player A leaves the room while player B hides an object somewhere in the room. Player

【转】[专题学习][计算几何]

原文地址:http://www.cnblogs.com/ch3656468/archive/2011/03/02/1969303.html 基本的叉积.点积和凸包等东西就不多说什么了,网上一搜一大堆,切一些题目基本熟悉了就差不多了. 一些基本的题目可以自己搜索,比如这个blog:http://blog.sina.com.cn/s/blog_49c5866c0100f3om.html 接下来,研究了半平面交,思想方法看07年朱泽园的国家队论文,模板代码参考自我校大牛韬哥: http://www.o