您的位置:首页 > 其它

算法竞赛入门经典(第2版)习题3-10 盒子 Box UVa1587

2014-07-13 17:58 459 查看
首先考虑长方体的性质,长方体有12条边,可以将其分为3组,每组4条边,这4条边可以认为分属4个矩形,其长度是相等的

依此判断所有12个能够构成长方体矩形的边最多只能有3种长度可能,每种可能至少要包含4个边,且这4个边要来自4个不同矩形

考虑此分类的特殊情况,如果出现长宽相等的矩形,那么只有以下2种特殊情况

1.所有12个边的长度将只能分为2种,一种包含8个边另一种包含4个边

2.所有12个边的长度都相等

校验逻辑

1.所有长宽数据按长度分类

2.每个分类可能包含的长度数量情况为(4,4,4)/(4,8)/(12),如果出现其他情况则输出”IMPOSSIBLE“

3.(4,4,4)情况,如果任意分类内有2条边来自同一个矩形则输出”IMPOSSIBLE“,否则输出”POSSIBLE“

4.(4,8)情况,如果数量为4的分类内有2条边来自同一个矩形则输出”IMPOSSIBLE“,否则输出”POSSIBLE“

5.(12)情况,输出”POSSIBLE“

理清逻辑、调试程序用了3、4个小时,一次AC


//#define LOCAL
//#define TESTING
#include<stdio.h>
#include<string.h>

main()
{
#ifdef LOCAL
freopen("xt3-10.in","r",stdin);
int T=1;
#endif

int l[12];
while(scanf("%d",&l[0])==1)
{
int fenlei[3],amt[3],ind1,ind2,flind[3][12],first[3];
bool ok = false;
memset(fenlei,0,sizeof(fenlei));
memset(amt,0,sizeof(amt));
memset(first,1,sizeof(first));
memset(flind,0,sizeof(flind));
#ifdef TESTING
printf("Case %d\n",T);
T++;
#endif
fenlei[0]=l[0];
flind[0][amt[0]]=0;
amt[0]++;

//读取数据
for(int i = 1; i < 12; i++)
{
scanf("%d",&l[i]);
}
//读取数据结束

//分类,设置分类开始位置标记,统计分类数量
for(int i = 1; i < 12; i++)
{
if(l[i] == fenlei[0])
{
flind[0][amt[0]]=i;
amt[0]++;
}
else if(first[0])
{
fenlei[1]=l[i];
flind[1][amt[1]]=i;
amt[1]++;
ind1=i;
first[0] = 0;
}
else if(l[i] == fenlei[1])
{
flind[1][amt[1]]=i;
amt[1]++;
}

else if(first[1])
{
fenlei[2] = l[i];
flind[2][amt[2]]=i;
amt[2]++;
ind2=i;
first[1] = 0;
}
else if(l[i] == fenlei[2])
{
flind[2][amt[2]]=i;
amt[2]++;
}
else break;
}
//分类,设置分类开始位置标记,统计分类数量结束

//校验(12)
if(amt[0]==12)
{
ok = true;
}
//校验(12)结束

//校验(4,8)/(8,4)
if((amt[0]==4)&&(amt[1]==8))
{
//检查分类0是否来自4个矩形
bool flag = true;
for(int i = 1; i < 4; i++)
{
int temp1=flind[0][i],temp2=flind[0][i-1];
if(temp1/2 == temp2/2)
{
flag = false;
break;
}
}
if(flag) ok = true;
//检查分类0是否来自4个矩形结束
}
else if((amt[0]==8)&&(amt[1]==4))
{
//检查分类1是否来自4个矩形
bool flag = true;
for(int i = 1; i < 4; i++)
{
int temp1=flind[1][i],temp2=flind[1][i-1];
if(temp1/2 == temp2/2)
{
flag = false;
}
}
if(flag) ok = true;
//检查分类1是否来自4个矩形
}
//校验(4,8)/(8,4) 结束

//校验(4,4,4)
if((amt[0]==4)&&(amt[1]==4)&&(amt[2]==4))
{
//检查分类0/1/2是否来自4个矩形
bool flag = true;
for(int i = 1; i < 4; i++)
{
int temp1=flind[0][i],temp2=flind[0][i-1];
int temp3=flind[1][i],temp4=flind[1][i-1];
int temp5=flind[2][i],temp6=flind[2][i-1];
if((temp1/2 == temp2/2)||(temp3/2 == temp4/2)||(temp5/2 == temp6/2))
{
flag = false;
}
}
if(flag) ok = true;
//检查分类0/1/2是否来自4个矩形结束
}
//校验(4,4,4) 结束

if(ok) printf("POSSIBLE\n");
else printf("IMPOSSIBLE\n");
#ifdef TESTING
for(int i = 0; i < 6; i++) printf("i=%d %d %d \n", i, l[2*i], l[2*i+1]);
for(int i = 0; i < 3; i++) printf("i=%d fenlei=%d amt=%d \n", i, fenlei[i], amt[i]);
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 8; j++) printf("flind[%d][%d]=%d /", i, j, flind[i][j]);
printf("\n");
}

printf("\n");
#endif

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: