2012 Multi-University Training Contest 9
❤题意:
给你一堆房子,给你一堆金矿的坐标。问有多少个三个房子的组合,使得这样的房子构成的区域里金矿的数量为奇数。
任意三点不共线。(场上理解错了,以为只有房子符合这个条件,其实是所有的点都符合这个条件。因为这个多判了好多东西,纠结了全场。摔)
❤思路:
场上的想法是:每两个点和零点组成一个三角形。查询多少个点在这样的三角形里。然后三次循环查询每三个点,对其两两与零点构成的三角形进行奇偶数判断。
但是麻烦的一点是,给出的任意三点不共线,可是任意两点和零点可能共线。
所以,改成了和第一个点构成三角形的。
P.S.原来的 oneside 的写法里,用的cross*cross,会报 long long 的!而且原来用的 int ,显然不行啊!
❤总结:
要读清题意!
要注意 int long long……
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
struct Polong
{
long long x,y;
}h[110],g[1010];
int lin[110][110];
inline long long cross(Polong a,Polong b,Polong c)
{
return (a.x-c.x)*(b.y-c.y)-(a.y-c.y)*(b.x-c.x);
}
int oneside(Polong xx,Polong yy,Polong zz,Polong qq)
{
if((cross(zz,xx,qq)>0&&cross(zz,yy,qq)>0)||(cross(zz,xx,qq)<0&&cross(zz,yy,qq)<0)){
return 1;
}
//return cross(zz,xx,qq)*cross(zz,yy,qq)>0;
}
int main()
{
int n,m;
int cas=1;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=1; i<=n; i++)
scanf("%I64d%I64d",&h[i].x,&h[i].y);
for(int i=1; i<=m; i++)
{
scanf("%I64d%I64d",&g[i].x,&g[i].y);
}
int ans;
int ansf=0;
for(int i=2; i<=n-1; i++)
{
for(int j=i+1; j<=n; j++)
{
ans=0;
for(int it=1; it<=m; it++)
if(oneside(g[it],h[i],h[j],h[1])&&oneside(g[it],h[1],h[i],h[j])&&oneside(g[it],h[j],h[i],h[1]))
ans++;
if(ans%2)
{lin[i][j]=1;ansf++;}
else
lin[i][j]=0;
}
}
for(int i=2; i<=n-2; i++)
{
for(int j=i+1; j<=n-1; j++)
{
for(int k=j+1; k<=n; k++)
{
ans=lin[i][j]+lin[i][k]+lin[j][k];
if(ans%2)
ansf++;
// prlong longf("~~%d %d %d\n",lin[i][j],lin[i][k],lin[j][k]);
// prlong longf("%d %d %d\n",i,j,k,ans);
}
}
}
printf("Case %d: %d\n",cas++,ansf);
}
return 0;
}
上次做了计算几何,这次会套用版儿了……泪目……