Inlay Cutters poj 2179

Description

The factory cuts rectangular M × N granite plates into pieces using a special machine that is able to perform cuts in 4 different directions: vertically, horizontally, and diagonally at the angle of 45 degrees to the sides of the plate. Every cut is a straight line that starts and ends on the side of the plate.



The factory has been ordered to produce tiles for the inlay, each tile of which is a 45 degrees right triangle. To reduce the time to deliver the tiles it was decided to take all triangles from the already cut plates. Information about all performed cuts is available and your task is to compute the number of triangles of any size that were produced.

Input

The input describes the cuts that were performed on a single rectangular plate. The first line of the input file contains three integer numbers M, N, and K, separated by spaces. M and N (1 ≤ M, N ≤ 50) are the dimensions of the plate, and K (0 ≤ K ≤ 296) is the number of cuts. Next K lines describe the cuts. ith cut is described by four integer numbers Xi,1, Yi,1, Xi,2, and Yi,2, separated by spaces, that represent the starting and ending point of the cut. Both starting (Xi,1, Yi,1) and ending (Xi,2, Yi,2) points of the cut are situated on the plate's border. Both points of the cut are different and the cut goes through the plate. Here, the coordinates by the X axis run from 0 to M, and the coordinates by the Y axis run from 0 to N. All cuts are different.

Output

Write to the output a single integer number - the number of triangles that were produced by the cuts.

Sample Input

7 4 6
6 0 7 1
1 4 1 0
0 4 4 0
0 0 4 4
0 2 7 2
7 0 3 4

Sample Output

8

这是一道简单的枚举题目,我的思路是开辟一个map数组用来保存这张图,一开始都赋值0,然后是进行各种切割,每一刀都自加,最后每个点的值都是>=2,而线上的值都是1,这样只要枚举每一个点是否是三角形的一个顶点即可。

接下来就是敲代码的活了。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>

int dir[8][4]={{-1,0,0,1},{-1,1,1,1},{0,1,1,0},{1,1,1,-1},{1,0,0,-1},{1,-1,-1,-1},{0,-1,-1,0},{-1,-1,-1,1}};   //三角形的不同判断方法
int map[201][201];

int Isxie(int x1,int y1,int x2,int y2,int c)
{
	int i;
	switch(c%4)
	{
		case 0:
			if(x1>x2)
			{
				for(i=x2+1;i<x1;i++)
					if(map[y2+i-x2][i]!=1)return 0;
				return 1;
			}
			else
			{
				for(i=x1+1;i<x2;i++)
					if(map[y1+i-x1][i]!=1)return 0;
				return 1;
			}
		case 1:
			if(y1>y2)
			{
				for(i=y2+1;i<y1;i++)
					if(map[i][x1]!=1)return 0;
				return 1;
			}
			else
			{
				for(i=y1+1;i<y2;i++)
					if(map[i][x1]!=1)return 0;
				return 1;
			}
		case 2:
			if(x1>x2)
			{
				for(i=x2+1;i<x1;i++)
					if(map[y2-i+x2][i]!=1)return 0;
				return 1;
			}
			else
			{
				for(i=x1+1;i<x2;i++)
					if(map[y1-i+x1][i]!=1)return 0;
				return 1;
			}
		case 3:
			if(x1>x2)
			{
				for(i=x2+1;i<x1;i++)
					if(map[y1][i]!=1)return 0;
				return 1;
			}
			else
			{
				for(i=x1+1;i<x2;i++)
					if(map[y1][i]!=1)return 0;
				return 1;
			}
	}
	return 0;
}
 //返回该点构成的三角形个数
int Istriangles(int x,int y,int M,int N)
{
	int nowx1,nowx2,nowy1,nowy2,c,sum=0;
	for(c=0;c<8;c++)
	{
	    nowx1=x;nowx2=x;nowy1=y;nowy2=y;
		if(nowy1+dir[c][0]<0||nowy1+dir[c][0]>M||nowx1+dir[c][1]<0||nowx1+dir[c][1]>N)continue;	
		if(nowy2+dir[c][0]<0||nowy2+dir[c][0]>M||nowx2+dir[c][1]<0||nowx2+dir[c][1]>N)continue;		
		nowy1=nowy1+dir[c][0];
		nowx1=nowx1+dir[c][1];
		nowy2=nowy2+dir[c][2];
		nowx2=nowx2+dir[c][3];
		if(map[nowy1][nowx1]*map[nowy2][nowx2]==0)continue;
		while(map[nowy1][nowx1]*map[nowy2][nowx2]==1)
		{
			nowy1=nowy1+dir[c][0];
			nowx1=nowx1+dir[c][1];
			nowy2=nowy2+dir[c][2];
			nowx2=nowx2+dir[c][3];
		}
		if(map[nowy1][nowx1]*map[nowy2][nowx2]==0)continue;
		if(map[nowy1][nowx1]==1||map[nowy2][nowx2]==1)continue;
		if(Isxie(nowx1,nowy1,nowx2,nowy2,c))sum++;
	}
	return sum;
}

int Find(int N,int M)
{
	int count=0;
	int i,j;
	for(i=0;i<=M;i++)
		for(j=0;j<=N;j++)
		{
			if(map[i][j]>1)
			{
				count=count+Istriangles(j,i,M,N);
			}
			else ;
		}
	return count;
}
int main()
{
	int N,M,K;
	while(scanf("%d%d%d",&M,&N,&K)!=EOF)
	{
		int i,j;
		memset(map,0,sizeof(map));
		for(i=0;i<=4*N;i++)
		{
			map[0][i]++;
			map[4*M][i]++;
		}
		for(i=0;i<=4*M;i++)
		{
			map[i][0]++;
			map[i][4*N]++;
		}
		while(K--)
		{
			int x1,x2,y1,y2;
			scanf("%d%d%d%d",&y1,&x1,&y2,&x2);
			int t=(y2-y1)*(x2-x1);
			if(t==0)
			{
				if(x1==x2)
				{
					if(y1<y2)
						for(j=4*y1;j<=4*y2;j++)
							map[j][4*x1]++;
					else
						for(j=4*y2;j<=4*y1;j++)
							map[j][4*x1]++;
				}
				else
				{
					if(x1<x2)
						for(j=4*x1;j<=4*x2;j++)
							map[4*y1][j]++;
					else
						for(j=4*x2;j<=4*x1;j++)
							map[4*y1][j]++;
				}
			}
			else if(t>0)
			{
				if(x1<x2)
					for(j=4*x1;j<=4*x2;j++)
						map[4*y1-4*x1+j][j]++;
				else
					for(j=4*x2;j<=4*x1;j++)
						map[4*y2-4*x2+j][j]++;
			}
			else if(t<0)
			{
				if(x1<x2)
					for(j=4*x1;j<=4*x2;j++)
						map[4*y1+4*x1-j][j]++;
				else
					for(j=4*x2;j<=4*x1;j++)
						map[4*y2+4*x2-j][j]++;
			}
			else ;
		}
		printf("%d\n",Find(4*N,4*M));
	}
	return 0;
}
希望交一些ACMer。。。。一起努力!!!一起奋斗!!!

转载于:https://www.cnblogs.com/cnwsycf/p/3335385.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值