hdu 4451 Dressing

本博客探讨了一个问题,即在特定服装搭配限制下,如何计算总组合数。问题涉及三种服装类型:上衣、裤子和鞋子,并且给出了某些不和谐搭配的规则。通过分析,我们了解到可以通过减去不和谐搭配的数量来找到允许的组合数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目地址: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<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<string>
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)直线和无交点的直线的数量。

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值