说说我的思路,每个盒子读入12个数,扫描,每找到一个数,就在12个数中找未被置零的数中与其相同的并置零(最开始的也置零),如果达到四个就break,然后继续找,如果扫描结束还未达到四个,就说明IMPOSSIBLE,
当12个数都空了,如果还未判断出IMPOSSIBLE,就利用在读入数据时计算出的每个面的面积,像刚才一样,6个数,找到一个未置零的,就在6个中找与其相同的,找到了,也置零,然后break,继续找,如果没找到,那么IMPOSSIBLE,
如果还未IMPOSSIBLE,那么输出POSSIBLE。
代码见下:
#include
#include
#include
using namespace std;
int rec[16],square[10];
int main()
{
freopen("New Text Document.txt","r",stdin);
freopen("Output.txt","w",stdout);
int x, y;
int flag;
while(scanf("%d%d", &x, &y) != EOF)
{
rec[0] = x;
rec[1] = y;
square[0] = x * y;
for(int i = 2; i < 12; i++)
{
scanf("%d", &rec[i]);
if(i%2) square[i/2] = rec[i] * rec[i-1];
}
//for(int i = 0; i < 6; i++) printf("%d ", square[i]);
for(int i = 0; i < 12; i++)
if(rec[i] != 0)
{
flag = 0;
x = rec[i];
for(int i = 0; i < 12; i++)
{
if(rec[i] == x)
{
flag++;
rec[i] = 0;
}
if(flag == 4) break;
}
if(flag != 4)
{
printf("IMPOSSIBLE\n");
flag = -1;
break;
}
}
if(flag != -1)
{
for(int i = 0; i < 6; i++)
if(square[i] != 0)
{
flag = 0;
x = square[i];
for(int i = 0; i < 6; i++)
{
if(square[i] == x)
{
flag++;
square[i] = 0;
}
if(flag == 2) break;
}
if(flag != 2)
{
printf("IMPOSSIBLE\n");
flag = -1;
break;
}
}
if(flag != -1)
printf("POSSIBLE\n");
}
}
return 0;
}
个人感觉我的方法还可以,这里有一个别人的代码,还是推荐去阅读原文:http://blog.csdn.net/kun768/article/details/43701899
#include
using namespace std;
struct face{
int x, y;
}a[6];
bool check()
{
if(memcmp(a, a+1, sizeof(face)) || memcmp(a+2, a+3, sizeof(face)) || memcmp(a+4, a+5, sizeof(face))) return false;
if(a[0].x!=a[2].x || a[0].y!= a[4].x || a[2].y!=a[4].y) return false;
return true;
}
int main()
{
while(cin >> a[0].x >> a[0].y >> a[1].x >> a[1].y >> a[2].x >> a[2].y >> a[3].x >> a[3].y >> a[4].x >> a[4].y >> a[5].x >> a[5].y){
for(int i = 0; i < 6; ++i)
if(a[i].x < a[i].y)
swap(a[i].x, a[i].y);
sort(a, a+6, [](const face a, const face b) {return a.x==b.x ? (a.y > b.y) : (a.x > b.x);});
printf("%s\n", check() ? "POSSIBLE" : "IMPOSSIBLE");
}
return 0;
}
下面这个是在网上看到的程序感觉思路不错,很有启发,
贴上来。
只要用一堆疯狂的条件分支就能解答此题了,如[KinderRiven](http://blog.csdn.net/u013451221/article/details/37672039)的代码。不过这里我更乐意把数据“标准化”,然后用C++构造“Face类”来求解。
首先构造一个宽w一定不小于高h的“面类(Face)”,并且按h为第一级,w为第二级准则从小到大排序。如果是能组成长方体的,边长肯定只有三种值,不妨设从小到大依次为a,b,c。则输入的6个面排序后,一定满足以下分布:
首先每种面肯定都出现了两次,即编号0、1相同,编号2、3相同,编号4、5相同。把这个准则,设计为测试函数test1。
接下来,编号0的h一定与编号2的h相等,编号0的w一定与编号4的h相等,编号2的w一定与编号4的w相等。把这个准则,设计为测试函数test2。
满足上述两个测试,是数据能组合成长方体的充要条件。
#include
#include
#include
using namespace std;
struct Face{
int h, w;
void make(int x, int y) {
h = min(x,y);
w = max(x,y);
}
bool operator < (const Face& b) const {
if (h == b.h) return w < b.w;
else return h < b.h;
}
bool operator == (const Face& b) const {
return (h == b.h) && (w == b.w);
}
};
vector A(6);
int test1() {
for (int i = 0; i < 6; i += 2) if (!(A[i]==A[i+1])) return 0;
return 1;
}
int test2() {
if (A[0].h==A[2].h && A[0].w==A[4].h && A[2].w==A[4].w) return 1;
else return 0;
}
int main() {
int x, y;
while (cin >> x >> y) {
A[0].make(x, y);
for (int i = 1; i < 6; i++) {
cin >> x >> y;
A[i].make(x, y);
}
sort(A.begin(), A.end());
if (test1() && test2()) cout << "POSSIBLE\n";
else cout << "IMPOSSIBLE\n";
}
return 0;
}
上述代码原文:http://blog.csdn.net/code4101/article/details/38303607