FOJ 1003 Counterfeit Dollar

       题目概述:有12枚硬币,编号'A'~‘L’。仅有一枚是假的,可能更轻也可能更重。现使用三次天平(每次两端放的硬币数量相同),出题人保证解唯一。请你通过三次测量情况,找出答案。

       输入:先出入测试组数n。然后每组输入3行,分别为每次天平左边放的硬币右边放的硬币右边天平情况

       输出:按格式输出,主要是确定12枚中哪每假,及其更轻还是更重。


       思路:如果想正向推导出结果,显然十分繁琐。其实结果只有12*2=24种情况,不如采用逆向思维,遍历24种情况,“用验证法求解答案”。如果其情况满足三次天平平衡情况,那么就是解。去年第一次做这题时,用C做,代码长度1700+,这次用C++做(用到string,find,npos),而且学会了C的memcmp(数组比较可用此函数)。不算注释,代码量约精简了一半。

#include <iostream>
#include <cstring>
#include <string>
using namespace std;

int main()
{
	int i, n, result[3];
	string left[3], right[3], temp, ans;
	
	cin >> n;
	while (n--)
	{
		for (i = 0; i < 3; i++)
		{
			cin >> left[i] >> right[i] >> temp;
			if (temp == "down") result[i] = -1;
			else if (temp == "even") result[i] = 0;
			else result[i] = 1;	// temp == "up"
		}
		
		char ch;
		for (ch = 'A'; ch <= 'L'; ch++)
		{
			int s[3];
			
			for (i = 0; i < 3; i++) 
				s[i] = (left[i].find(ch)!=left[i].npos) - (right[i].find(ch)!=right[i].npos);
			// 注意: 上行括号是必须加的,因为减法优先级大于!= 

			if (!memcmp(s, result, sizeof(int)*3)) // memcmp() form <cstring> 
			{ 
				ans = "heavy";
				break;
			}
			
			for (i = 0; i < 3; i++) s[i] = -s[i]; 
			if (!memcmp(s, result, sizeof(int)*3)) 
			{ 
				ans = "light";
				break;
			}
		}
		cout << ch << " is the counterfeit coin and it is " << ans << ".\n";
	}
	return 0;
}




你可能感兴趣的:(ACM)