To Be an Dream Architect(2010年ACM亚洲预选赛杭州赛区第三题))

ProblemC. To Be an Dream Architect

Description

The “dreamarchitect” is the key role in a team of “dream extractors” who enter other’sdreams to steal secrets. A dream architect is responsible for crafting the virtualworld that the team and the target will dream into. To avoid the targetnoticing the world is artificial, a dream architect must have powerful 3Dimagination.

Cobb uses a simple3D imagination game to test whether a candidate has the potential to be andream architect. He lets the candidate imagine a cube consisting of n×n×nblocks in a 3D coordinate system as Figure 1. The block at bottom left frontcorner is marked (1, 1, 1) and the diagonally opposite block is marked (n, n,n). Then he tells the candidate that the blocks on a certain line areeliminated. The line is always parallel to an axis. After m such blockeliminations, the candidate is asked to tell how many blocks are eliminated.Note that one block can only be eliminated once even if it is on multiplelines.

Here is a samplegraph according to the first test case in the sample input:


Input

The first line isthe number of test cases.

In each test case,the first line contains two integers n and m( 1 <= n <= 1000, 0 <= m<= 1000).,meaning that the cube is n x n x n and there are meliminations.

Each of thefollowing m lines represents an elimination in the following format:

axis_1=a, axis_2=b

where axis_i (i=1,2) is ‘X’ or ‘Y’, or ‘Z’ and axis_1 is not equal to axis_2. a and b are 32-bitsigned integers.

Output

For each test caseoutput the number of eliminated blocks.

Sample Input

2

3 2

Y=1,Z=3

X=3,Y=1

10 2

X=3,Y=3

Y=3,Z=3

Sample Output

5

19

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

#define MAX 100

typedef	struct Line
{
	char axis1,axis2;
	int value1,value2;
	bool legal;
}Line;

void getLine();//获得消去线的坐标,并保证数据的合法性,即无越界、重复
int getnum_cube();//获取整个立方体的消去块数

int n,m;
Line line[MAX];
bool x[MAX],y[MAX];

int main()
{
	int i;
	int test_num;//测试数据组数
	scanf("%d",&test_num);
	for(i=0;i<test_num;i++)
	{
		getLine();
		printf("%d\n",getnum_cube());
	}
	system("pause");
	return 0;
}

void getLine()//获得消去线的坐标
{
	int i,j;
	scanf("%d%d",&n,&m);
	getchar();
	for(i=0;i<m;i++)//获得m组消去线的坐标
	{
		scanf("%c",&line[i].axis1);
		scanf("=%d",&line[i].value1);
		getchar();
		scanf("%c",&line[i].axis2);
		scanf("=%d",&line[i].value2);
		getchar();
		
		if(line[i].axis1>line[i].axis2)//保证第一个坐标总是小于第二个
		{
			char ch=line[i].axis1;
			line[i].axis1=line[i].axis2;
			line[i].axis2=ch;

			j=line[i].value1;
			line[i].value1=line[i].value2;
			line[i].value2=j;
		}
	}
	i=0;j=m-1;
	while(i<j)//对数据排序使Z有值的优先处理
	{
		while(i<j&&line[i].axis2=='Z')
			i++;
		while(i<j&&line[j].axis2!='Z')
			j--;
		if(i<=j)//交换元素记录
		{
			Line temp=line[i];
			line[i]=line[j];
			line[j]=temp;
		}
	}
	for(i=0;i<m;i++)
	{
		if(line[i].value1<=n&&line[i].value1>=1&&line[i].value2<=n&&line[i].value2>=1)//无越界
		{
			line[i].legal=true;
			for(j=0;j<i;j++)
				if(line[i].axis1==line[j].axis1&&line[i].axis2==line[j].axis2)//无重复
					if(line[i].value1==line[j].value1&&line[i].value2==line[j].value2)
						line[j].legal=false;
		}
		else
			line[i].legal=false;
    }
}
int getnum_cube()//获取整个立方体的消去块数
{
	int i,j,v,w;
	int num_x,num_y,num_z;//每一层中x、y、z方向消去线的个数
	int sum;
	sum=0;
	for(i=0;i<n;i++)
	{
		for(j=0;j<n;j++)
		{
			x[j]=y[j]=false;
		}
		num_x=0;
		num_y=0;
		num_z=0;
		for(j=0;j<m;j++)
			if(line[j].legal==true)
			{		
				if(line[j].axis1=='X'&&line[j].axis2=='Z'&&line[j].value2==(i+1))
				{
					x[line[j].value1-1]=true;
					num_x++;
				}
				else if(line[j].axis1=='Y'&&line[j].axis2=='Z'&&line[j].value2==(i+1))
				{
					y[line[j].value1-1]=true;
					num_y++;
				}
				else if(line[j].axis1=='X'&&line[j].axis2=='Y')
				{
					if(x[line[j].value1-1]||y[line[j].value2-1])//如果此行或此列已被选中,则num_z不增加
					{}
					else
					num_z++;
				}
			}
		sum+=(num_x+num_y)*n+num_z-num_x*num_y;
		
	}
	return sum;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值