Attack on Titan(状态压缩)

Attack on Titan

 

WL大神最近迷上了一款名叫《神话时代》的游戏,这个游戏里有一种非常强力的兵种——泰坦,可以不费吹灰之力地摧毁一座座村庄。但是,泰坦有一个弱点,就是不能过河。有一次,WL大神玩了一个布满河流的地图,这个地图上坐落着N个村庄,M条河流(每条河流都可以视作一条横跨地图的直线)。WL大神一口气使用“TITANOMACHY”秘籍在一些地点共召唤了K个泰坦。现在,WL大神想知道都有哪些村庄可以被摧毁。

Input

输入数据有多组。

第一行输入一个整数T(T≤10),表示数据组数。

每组数据第一行为三个整数N(N≤50000)、K(K≤50000)、M(M≤50),分别代表村庄数、泰坦数、河流数。

接下来N行每行两个整数x、y(0≤x,y≤10^6),代表第i个村庄的坐标。

接下来K行每行两个整数x、y(0≤x,y≤10^6),代表第i个泰坦的坐标。

接下来M行每行四个整数x1、y1、x2、y2(0≤x1,y1,x2,y2≤10^6),代表第i条河流流经的两个点,保证(x1,y1)与(x2,y2)不重合,保证村庄和泰坦不会在任何一条河流上。

Output

每组数据输出N行,如果第i个村庄可以被摧毁则在第i行输出1,否则输出0。

Sample Input

1
2 1 1
0 0
2 0
2 2
1 0 1 1

Sample Output

0
1

Source

Author

hwq

 

 

记录每个泰坦相对每条河流的位置,然后在来判断每个村庄相对河流的位置,用状态压缩存;这里特别注意的是,用map<string,bool>,一开始,我们用map<long long,bool>,结果就WA了。。。T^T .今天好忧桑,各种WA。。。

 

转载请注明出处:http://blog.csdn.net/u010579068/article/details/45606905

 

题目链接:http://www.bnuoj.com/bnuoj/problem_show.php?pid=49099

 

 

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#include <algorithm>
using namespace std;
#define ls 2*i
#define rs 2*i+1
#define up(i,x,y) for(i=x;i<=y;i++)
#define down(i,x,y) for(i=x;i>=y;i--)
#define mem(a,x) memset(a,x,sizeof(a))
#define w(a) while(a)
#define LL long long
const double pi = acos(-1.0);
#define N 50005
#define mod 19999997
const int INF = 0x3f3f3f3f;
#define exp 1e-8

struct Point
{
    LL x,y;
    Point(LL x=0,LL y=0):x(x),y(y) {} //构造函数,方便代码编写

};

typedef Point Vector;//Vector只是Point的别名

//向量+向量=向量;    向量+点=点
Vector operator + (Vector A,Vector B)
{
    return Vector(A.x+B.x,A.y+B.y);
}

//点-点=向量
inline Vector operator - (Point A,Point B)
{
    return Vector(A.x-B.x,A.y-B.y);
}

inline bool Cross(Vector A,Vector B)
{
    return A.x*B.y>B.x*A.y?true:false;
}
inline bool judge(Point A,Point B,Point C)
{
    return Cross(B-A,C-A);
}

map<string,bool> vis;
Point a[N],b[N],c[55][2];

int main()
{
    LL t,i,j;
    LL n,m,k;
    scanf("%lld",&t);
    w(t--)
    {
        vis.clear();
        scanf("%lld%lld%lld",&n,&m,&k);
        up(i,0,n-1)
        {
            scanf("%lld%lld",&a[i].x,&a[i].y);
        }
        up(i,0,m-1)
        {
            scanf("%lld%lld",&b[i].x,&b[i].y);
        }
        up(i,0,k-1)
        {
            scanf("%lld%lld%lld%lld",&c[i][0].x,&c[i][0].y,&c[i][1].x,&c[i][1].y);
        }
        up(i,0,m-1)
        {
            string s = "";
            up(j,0,k-1)
            {
                if(judge(c[j][0],c[j][1],b[i]))
                    s+="1";
                else
                    s+="0";
            }
            s+="";
           // printf("s1= %lld\n",s);
            vis[s] = true;
        }
        up(i,0,n-1)
        {
            string s = "";
            up(j,0,k-1)
            {
                if(judge(c[j][0],c[j][1],a[i]))
                    s+="1";
                else
                    s+="0";
            }
            s+="";
       //     printf("s2= %lld\n",s);
            if(vis[s]==true)
                printf("1\n");
            else
                printf("0\n");
        }
    }

    return 0;
}


 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值