zoukankan      html  css  js  c++  java
  • SPOJ

    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
    ",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

     

  • 相关阅读:
    2012年几大传统编程语言就业趋势分析
    解决vs2010 utimate中文版添加Silverlight for WP7模板方案【WP7学习札记之一】
    ASP.NET中的加密与解密
    先睹为快:Visual Studio 11测试版已于2.29在微软官方网站正式发布
    五种常见的ASP.NET安全缺陷
    WP7开发平台介绍及开发注意事项【WP7学习札记之二】
    简单工厂模式【设计模式学习01】
    单例的若干实现总结与拓展
    按照“红线准则”设计布局【WP7学习札记之三】
    几个解放双手的 Go 开发利器
  • 原文地址:https://www.cnblogs.com/Aragaki/p/7026068.html
Copyright © 2011-2022 走看看