简单的计算几何(整数几何)。
题目中数据出的并不大,所以直接枚举所有点,判断是否在范围内即可(以及判重)。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define sign(a) ((a)>0?1:(((a)<0?-1:0)))
using namespace std;
int n,m;
int flg[152][152];
int cx[52],cy[52],cr[52];
int sx[52],sy[52],sl[52];
struct Point{
int x,y;
Point(){}
Point(int a,int b){x=a,y=b;}
}t[52][3];
int xmult(Point p,Point l1,Point l2){
return (p.x-l2.x)*(l1.y-l2.y)-(l1.x-l2.x)*(p.y-l2.y);
}
int di(Point p,Point l1,Point l2){ // 判断点是否在线段上
return !xmult(p,l1,l2) && (l1.x-p.x)*(l2.x-p.x)<=0 && (l1.y-p.y)*(l2.y-p.y)<=0;
}
int sd(Point p1,Point p2,Point l1,Point l2){ // 判断p1、p2是否在线段同侧
return sign(xmult(l1,p1,l2))*xmult(l1,p2,l2)>0;
}
int deal(int i,Point p){
if(di(p,t[i][0],t[i][1]) || di(p,t[i][0],t[i][2]) || di(p,t[i][1],t[i][2])) return 1;
if(sd(p,t[i][0],t[i][1],t[i][2]) && sd(p,t[i][1],t[i][0],t[i][2]) && sd(p,t[i][2],t[i][1],t[i][0]))
return 1;
return 0;
}
int main(){
int T,n,i,j,cnt1,cnt2,cnt3,x,y,sum,l1,l2,r1,r2;
char ch[3];
scanf("%d",&T);
while(T--){
scanf("%d",&n);
cnt1=cnt2=cnt3=0;
while(n--){
scanf("%s",ch);
if(ch[0]=='C'){
scanf("%d%d%d",&cx[cnt1],&cy[cnt1],&cr[cnt1]);
cnt1++;
}
else if(ch[0]=='S'){
scanf("%d%d%d",&sx[cnt2],&sy[cnt2],&sl[cnt2]);
cnt2++;
}
else{
for(i=0;i<3;i++)
scanf("%d%d",&t[cnt3][i].x,&t[cnt3][i].y);
cnt3++;
}
}
sum=0;
memset(flg,0,sizeof(flg));
for(i=0;i<cnt1;i++){
l1=cx[i]-cr[i];
r1=cx[i]+cr[i];
l2=cy[i]-cr[i];
r2=cy[i]+cr[i];
for(x=l1;x<=r1;x++)
for(y=l2;y<=r2;y++)
if(flg[x+50][y+50]) continue;
else if((cx[i]-x)*(cx[i]-x)+(cy[i]-y)*(cy[i]-y)<=cr[i]*cr[i]){
flg[x+50][y+50]++;
sum++;
}
}
for(i=0;i<cnt2;i++){
l1=sx[i];
r1=sx[i]+sl[i];
l2=sy[i];
r2=sy[i]+sl[i];
for(x=l1;x<=r1;x++)
for(y=l2;y<=r2;y++)
if(flg[x+50][y+50]) continue;
else{
flg[x+50][y+50]++;
sum++;
}
}
for(i=0;i<cnt3;i++){
l1=min(t[i][0].x,min(t[i][1].x,t[i][2].x));
r1=max(t[i][0].x,max(t[i][1].x,t[i][2].x));
l2=min(t[i][0].y,min(t[i][1].y,t[i][2].y));
r2=max(t[i][0].y,max(t[i][1].y,t[i][2].y));
for(x=l1;x<=r1;x++)
for(y=l2;y<=r2;y++)
if(flg[x+50][y+50]) continue;
else if(deal(i,Point(x,y))){
flg[x+50][y+50]++;
sum++;
}
}
printf("%d\n",sum);
}
return 0;
}