hdu 4451 Dressing

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4451

 

题目描述:

Dressing

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 919    Accepted Submission(s): 414


Problem Description
      Wangpeng has N clothes, M pants and K shoes so theoretically he can have N×M×K different combinations of dressing.
      One day he wears his pants Nike, shoes Adiwang to go to school happily. When he opens the door, his mom asks him to come back and switch the dressing. Mom thinks that pants-shoes pair is disharmonious because Adiwang is much better than Nike. After being asked to switch again and again Wangpeng figure out all the pairs mom thinks disharmonious. They can be only clothes-pants pairs or pants-shoes pairs.
       Please calculate the number of different combinations of dressing under mom’s restriction.
 


 

Input
       There are multiple test cases.
       For each case, the first line contains 3 integers N,M,K(1≤N,M,K≤1000) indicating the number of clothes, pants and shoes.
       Second line contains only one integer P(0≤P≤2000000) indicating the number of pairs which mom thinks disharmonious.
       Next P lines each line will be one of the two forms“clothes x pants y” or “pants y shoes z”.
The first form indicates pair of x-th clothes and y-th pants is disharmonious(1≤x≤N,1 ≤y≤M), and second form indicates pair of y-th pants and z-th shoes is disharmonious(1≤y≤M,1≤z≤K).
       Input ends with “0 0 0”.
It is guaranteed that all the pairs are different.
 


 

Output
       For each case, output the answer in one line.
 


 

Sample Input
 
   
2 2 2 0 2 2 2 1 clothes 1 pants 1 2 2 2 2 clothes 1 pants 1 pants 1 shoes 1 0 0 0
 


 

Sample Output
 
   
8 6 5

 

 

题意:有上衣 裤子  鞋子 的任意搭配,给出特定的两种搭配,问此两种搭配不能出现的所有搭配数数多少。即总搭配数 - 特定条件搭配  = 答案

 

题解:这里有上衣 裤子 鞋子 三个因素,不妨看成三个坐标方向,即上衣是x轴  裤子是y轴  鞋子是z轴,这样问题就抽象为,给出一个x*y*z的具体大小的三维空间,其中特定条件

           为(x,y)的直线 或  (y,z)的直线,问总三维空间的点数(即x*y*z)减去  特定条件给出的直线所占的点的数量  后 剩余点的数量。而直线所占点的数量依赖于未确定

           那一维的大小,如有三维空间(10,12,20)  那么直线(10,12)所占三维空间的点的数量就是20。如果特定条件给出的直线没有交点 那么来一条直线就减去它所占的

           的点数,如果有交点那么就记录有多少条(x,y)的点交到(y,z)上,即来一条(y,z)就减去其x,而来一条(x,y),就记录以y为索引这样的(x,y)直线有多少条

          方便后面减去重复点个数(防止多减去了点)。这样,最后遍历下记录出来的(x,y)记录集,减去有重复点(即与(y,z)有交点)的直线。即是最终答案。还是看代码

          把,感觉解释的不是很清楚。

代码:

#include
#include
#include
#include
#include
#include
using namespace std;
int N=0,M=0,K=0,P=0;
char Str1[10+5],Str2[10+5];
int s1=0,s2=0;
int ys[1000+5];
int yss[1000+5];
int counts=0;
/*for test*/
int test()
{
	return(0);
}
/*main process*/
int MainProc()
{
	while(scanf("%d%d%d",&N,&M,&K)!=EOF&&(N>0||M>0||K>0))
	{
		scanf("%d",&P);
		memset(yss,0,sizeof(yss));
		memset(ys,0,sizeof(ys));
		counts=N*M*K;
		int i=0;
		for(i=1;i<=P;i++)
		{
			scanf("%s%d%s%d",Str1,&s1,Str2,&s2);
			if(Str1[0]=='c')//y is s2
			{
				ys[s2]++;//record the repeat point
			}
			else//y is s1
			{
				counts-=N;
				yss[s1]++;
			}
		}
		for(i=1;i<=M;i++)
		{
			if(ys[i]>0)
			{
				for(int j=1;j<=ys[i];j++)
				counts-=(K-yss[i]);
			}
		}
		printf("%d\n",counts);
	}
	return(0);
}
int main()
{
	MainProc();
	return(0);
}


 

 

 

 

ys数组记录(x,y)的直线,以y为索引。yss记录(y,z)的直线,亦即可能出现交点的个数,以y为索引。以y为索引的原因是,(x,y)直线与(y,z)直线若要存在交点,那么两者的y必须相等。

这样第一个for相当于是减去所有的(y,z)直线上的点。最后遍历ys数组是减去(x,y)直线以及与(y,z)直线有交点的直线的所占点的数量,ys[i]>0表示这里有(x,y)

直线需要减去,然后遍历ys[i]的内容表示要减去该y坐标的多条(x,y)直线,注意这里是多条不是一条,因为x可以变化。然后再减去有交点的(x,y)直线和无交点的直线的数量。

 

 

 

 

 

 

 

 

你可能感兴趣的:(ACM_数学)