SPOJ - AMR11B 判断是否在三角形 正方形 圆形内

 

Hogwarts is under attack by the Dark Lord, He-Who-Must-Not-Be-Named. To protect the students, Harry Potter must cast protective spells so that those who are protected by the spells cannot be attacked by the Dark Lord.

Harry has asked all the students to gather on the vast quidditch sports field so that he can cast his spells.  The students are standing in a 2D plane at all grid points - these are the points (x,y) such that both x and y are integers (positive, negative or 0). Harry's spell can take the shapes of triangle, circle or square, and all who fall within that shape (including its boundaries) are protected.

Given the types of spells and the details regarding where Harry casts the spell, output the number of people saved by Harry's spells.

Input (STDIN):

The first line contains the number of test cases T. T test cases follow.

Each case contains an integer N on the first line, denoting the number of spells Harry casts. N lines follow, each containing the description of a spell.

If the ith spell is a triangle, then the line will be of the form "T x1 y1 x2 y2 x3 y3". Here, (x1,y1), (x2,y2) and (x3,y3) are the coordinates of the vertices of the triangle.

If the ith spell is a circle, then the line will be of the form "C x y r". Here, (x,y) is the center and r is the radius of the circle.

If the ith spell is a square, then the line will be of the form "S x y l". Here, (x,y) denotes the coordinates of the bottom-left corner of the square (the corner having the lowest x and y values) and l is the length of each side.

 

Output (STDOUT):

Output T lines, one for each test case, denoting the number of people Harry can save.

 

Constraints:

All numbers in the input are integers between 1 and 50, inclusive.

The areas of all geometric figures will be > 0.

 

Sample Input:

4

1

C 5 5 2

1

S 3 3 4

1

T 1 1 1 3 3 1 

3

C 10 10 3

S 9 8 4

T 7 9 10 8 8 10

 

Sample Output:

13

25

6

34

是否在圆内的判断使用到圆心的距离,遍历范围x±r,y±r,是否在正方形内直接判断,数据范围x->x+r,y->y+r,是否在三角形内部,一般有以下两种方法,一是利用面积来判断,对于三角形ABC,任取一个点M,连接M与ABC三个顶点,构成了三个三角形,三个三角形的和若等于原三角形的和,则在内部,否则在外部,但是利用海伦公式求面积时,浮点数会引起误差,一般推荐使用另一种方法,即是计算MA*MB、MB*MC、MC*MA的大小,若这三个值同号,那么在三角形的内部,异号在外部

#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <stack>
#include <cstdio>
using namespace std;
  
#define ss(x) scanf("%d",&x)
#define print(x) printf("%d\n",x)
#define ff(i,s,e) for(int i=s;i<e;i++)
#define fe(i,s,e) for(int i=s;i<=e;i++)
#define write() freopen("1.in","r",stdin)
  
int m[210][210];
struct Point{
    int x,y;
}a,b,c,d;
int x,y,r;
int calmul(Point aa,Point bb,Point cc){  // 计算向量AB 与向量AC的叉乘
    return (bb.x-aa.x)*(cc.y-aa.y)-(cc.x-aa.x)*(bb.y-aa.y);
}
bool intr(int i,int j){//如果DA*DB、DB*DC、DC*DA同号,则在三角形内部
    int t1,t2,t3;
    d.x = i;d.y = j;
    t1 = calmul(d,a,b);
    t2 = calmul(d,b,c);
    t3 = calmul(d,c,a);
    if(t1<=0 && t2 <=0 && t3 <=0)return 1;
    if(t1>=0 && t2 >=0 && t3 >=0)return 1;
    return 0;
}
void solve(){
    char str[10];
    int n,cnt=0;
    memset(m,0,sizeof(m));
    ss(n);
    while(n--){
        scanf("%s",str);
        switch(str[0]){
        case'C'://圆通过到圆心的距离判断
            scanf("%d%d%d",&x,&y,&r);
            x+=100;y+=100;//避免坐标为负值,输入全部加上100
            fe(i,x-r,x+r)
            fe(j,y-r,y+r)
            if(!m[i][j]&& ((x-i)*(x-i)+(y-j)*(y-j)<=r*r)){
                cnt++;
                m[i][j]=1;
            }
            break;
        case'T'://三角形通过叉乘来判断
            scanf("%d%d%d%d%d%d",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y);
            a.x+=100;b.x+=100;c.x+=100;a.y+=100;b.y+=100;c.y+=100;
            fe(i,100,200)
            fe(j,100,200)
            if(!m[i][j] && intr(i,j)){
                cnt++;
                m[i][j]=1;
            }
            break;
        case'S'://正方形的判断
            scanf("%d%d%d",&x,&y,&r);
            x+=100;y+=100;
            fe(i,x,x+r)
            fe(j,y,y+r)
            if(!m[i][j]){
                cnt++;
                m[i][j]=1;
            }
        }
    }
    print(cnt);
}
int main(){
    //write();
    int T;
    ss(T);
    while(T--){
        solve();
    }
}
View Code

 

 

转载于:https://www.cnblogs.com/Aragaki/p/7026068.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值