HDU4451 Dressing
王鹏有N件衣服,M件裤子,K双靴子,所以理论上他有N*M*K种搭配方式。但是他的妈妈不喜欢王鹏德一些衣服—裤子或者裤子—鞋子的搭配。所以现在要你求王鹏到底有多少种搭配方式。
输入:输入包含多个实例。第一行是N,M,K三个数。(1≤N,M,K≤1000)。第二行包含一个整数P(0≤P≤2000000),表有多少对不合适。以下P行分别为“clothes x pants y” or “pants y shoes z”.表示第x个衣服与第y个裤子不合适(1≤x≤N,1 ≤y≤M) 或者 第y个裤子与第z个鞋子不合适(1≤y≤M,1≤z≤K)。输入以0 0 0表示结束。
输出:合适搭配的总数。
分析:
本题其实就是容斥原理加枚举。
解法一:此解法注意不要有遗漏的情况!
设总数为S=N*M*K,冲突1类“clothes x pants y”的个数为A,冲突2类“pants y shoes z”的个数为B个。
则合适搭配的总数为:S-A*K-B*N+O.其中O是A与B重叠的个数。如clothes 1 pants 2与pants 2shoes 5 重叠的O值为1,指的是情况
clothes 1 pants 2 shoes 5。
注意pants 2 shoes 5与pants 2shoes 6可以共存的。其实裤子k可以分别与鞋子1,2,3,4,5,6都冲突。
其实这道题目就是容斥原理加枚举的运用。
AC代码:
#include<cstdio>
#include<cstring>
using namespace std;
int a[200+1000],b[200+1000];//a[i]=j,表示i裤子与j衣服冲突,b[i]=j表i裤子与j鞋子冲突。
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,m,k;
while(scanf("%d%d%d",&n,&m,&k)==3)//衣服,裤子,鞋子数目
{
if(n==0&&m==0&&k==0)break;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
int p;
intsum=0;//合适的搭配总数
char s1[100],s2[100];
int x,y;
intA=0,B=0;//A表衣服-裤子冲突总数,B表裤子-鞋子冲突总数
intO=0;//A与B中多删除了一次重叠的个数
scanf("%d",&p);
while(p--)
{
scanf("%s%d%s%d",s1,&x,s2,&y);
if(strcmp(s1,"clothes")==0)
{
A++;
a[y]++;
}
elseif(strcmp(s1,"pants")==0)
{
b[x]++;
B++;
}
}
for(inti=1; i<=m; i++)
{
if(a[i]!=0)
O+=a[i]*b[i];//鞋子i所产生的重叠的个数
}
sum =n*m*k-A*k-B*n+O;
printf("%d\n",sum);
}
return 0;
}
解法二:
其实合适搭配总数为:各个鞋子的sum值之和。
Sum[i]表示第i个鞋子合适搭配的数目=可以与i搭配的衣服数*可以与i搭配的鞋子数。
AC代码:
#include<cstdio>
#include<cstring>
using namespace std;
int a[200+1000],b[200+1000];//a[i]=j,表示i裤子与j衣服冲突,b[i]=j表i裤子与j鞋子冲突。
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,m,k;
while(scanf("%d%d%d",&n,&m,&k)==3)
{
if(n==0&&m==0&&k==0)break;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
int p;
intsum=0;
chars1[100],s2[100];
int x,y;
intA=0,B=0;
int O=0;
scanf("%d",&p);
while(p--)
{
scanf("%s%d%s%d",s1,&x,s2,&y);
if(strcmp(s1,"clothes")==0)
{
A++;
a[y]++;
}
elseif(strcmp(s1,"pants")==0)
{
b[x]++;
B++;
}
}
for(inti=1; i<=m; i++)
{
//if(a[i]!=0)
// O+=a[i]*b[i];
sum+= (n-a[i])*(k-b[i]);
//printf("O is : %d\n",O);
}
//sum =n*m*k-A*k-B*n+O;
printf("%d\n",sum);
}
return 0;
}