UVA - 1587 Box

/*
  起初自己的思路是没有这么简洁清晰的,后来做完以后,想要去搜下别人是怎么做的,搜到了这篇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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值