/*
起初自己的思路是没有这么简洁清晰的,后来做完以后,想要去搜下别人是怎么做的,搜到了这篇blog
http://blog.csdn.net/kun768/article/details/43701899
发现别人的代码真是清晰又简洁,于是自己也改写了自己的代码,采用了博主的思路,并且加上了一些重载
另外,上面那个博客链接的代码,可真是优美,值得一看
同时,这也启发我们,每次oj做完一道题,都应该搜下别人是怎么做的。同样的代码,为什么别人就能写得这么简洁,时时总结,才会有更大的收获
*/
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
struct face
{
int w, h;
}a[6];
istream& operator >> (istream&in, face& f)
{
in >> f.w >> f.h;
if (f.w < f.h) swap(f.w, f.h);
return in;
}
bool operator < (const face&e, const face&f)
{
return (e.w == f.w)?(e.h > f.h):(e.w > f.w);
}
bool check()
{
for (int i = 0; i < 6; i += 2)
if (memcmp(a + i, a + i + 1, sizeof(face))) return false; // 用memset()函数,比较自定义的结构体数组中的元素,会很简便
if (a[0].w != a[2].w || a[0].h != a[4].w || a[2].h != a[4].h) return false;
return true;
}
int main()
{
while (cin >> a[0])
{
for (int i = 1; i < 6; i++) cin >> a[i];
sort(a, a + 6);
cout << ( check()? "POSSIBLE":"IMPOSSIBLE" ) << endl;
}
return 0;
}
/*
另外,后来又找到一串更简洁的代码,来自这个blog:
http://blog.csdn.net/qq_27474589/article/details/75270349
它是利用了pair的自动排序,因为pair默认先按first,再按second排序,所以就不用重载小于号了,算是用pair的一个简便之处...
于是我也自己利用pair写了一次
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef pair<int, int> p;
p box[6];
bool check()
{
for (int i = 0; i < 6; i += 2)
if (box[i] != box[i + 1]) return false;
if (box[2].first != box[4].first || box[4].second != box[0].first || box[0].second != box[2].second) return false;
return true;
}
int main()
{
while (1)
{
for (int i = 0; i < 6; i++)
{
// cin >> box[i].first >> box[i].second;
// 要能成功退出,而非进入死循环,应该利用scanf的返回值
if (scanf("%d%d",&box[i].first, &box[i].second) != 2) return 0;
if (box[i].first < box[i].second) swap(box[i].first, box[i].second);
}
sort(box, box + 6);
cout << ( check()? "POSSIBLE":"IMPOSSIBLE" ) << endl;
}
return 0;
}
/*
但是比赛的时候,可能并不能刚好就能想到这么简便的代码,这种代码可以总结时看,但最好还是不要期待,自己在需要临场应变的时候,也能写出这么思路清晰又简洁的代码
还是要熟练掌握,我们一般能直接想到的那种方法,我自己重写时参考了
http://blog.csdn.net/thudaliangrx/article/details/50699439
*/
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int a[12], b[12];
int side[3]; //长方形最多3种边
int cnt[3]; // 最多三种面
int main()
{
while(cin >> a[0] >> a[1])
{
for (int i = 2; i < 12; i++) cin >> a[i];
for (int i = 0; i < 12; i += 2)
if (a[i] > a[i + 1]) swap(a[i], a[i + 1]); //对每个面的两条边,内部交换使得后一条边更大
memcpy(b, a, sizeof(a));
sort(a, a + 12);
bool flag = true;
for (int i = 0; i < 3; i++)
{
side[i] = a[4 * i];
for (int j = 1; j < 4; j++)
{
if (side[i] != a[4 * i + j])
{
flag = false;
break;
}
}
} //保证一共最多3种边,且每边4条
if (flag)
{
memset(cnt, 0, sizeof(cnt));
for (int i = 0; i < 12; i += 2) //到此处已经满足:side数组的元素升序排列,对于每个面而言,b数组中,该面较短的一边在前;于是再来判断6个面,是否可分为3组,且每组至多两个
{
if( cnt[0] < 2 && b[i] == side[0] && b[i + 1] == side[1]) cnt[0]++;
else if ( cnt[1] < 2 && b[i] == side[1] && b[i + 1] == side[2]) cnt[1]++;
else if ( cnt[2] < 2 && b[i] == side[0] && b[i + 1] == side[2] ) cnt[2]++;
else
{
flag = false;
break;
}
// 注意一定要有 cnt[0/1/2] < 2这个判断,否则,当三种边有两个相等,或者三个相等的情况,就可能某个cnt为4,而另一个为0,甚至某个cnt为6,其他两个为0,这种情况其实仍能构成长方形,但如果不加 < 2 的判断条件,我原先的代码就会将它作为不满足处理,导致WA
}
if (!(cnt[0] == 2 && cnt[1] == 2)) flag = false;
}
cout << (flag? "POSSIBLE" : "IMPOSSIBLE") << endl;
}
return 0;
}
UVA - 1587 Box
最新推荐文章于 2024-11-12 21:59:57 发布