HDU

/*
------------------------感慨------------------------
  后来查了一下,大家似乎是把这道题作为水题的...
  
  可我想了很久...确切说,理解题意都用了很久,以及大家博客上的代码,我最初看时还一直看不懂...后来才发现其实没那么难,唉,看来我基础真的太薄弱,做的题目还是太少了,大家口中的水题,我还是得一题题写,稳扎稳打...嗯
------------------------感慨结束------------------------
  
  总结这道题吧:
  
  每个数字都有一个LED表示,我们可以知道每个数字的LED表示,对应的X是多少
  
  数字及其LED表示以此为:前面为X的个数,括号为对应的数字,多个表示有多个数字的表示具有相同的X个数
  4(1), 6(7), 8(4), 14(8), 10(2/5/3), 12(5/6/0)
  
  于是X的个数为14和10的时候,需要结合X的分布来确定表示的数字是什么,其他情况下,就可以通过X的个数,直接判断个数了
  
  BTW:
  如果仅仅只是4个数字,16列似乎就够了,其他5列,要么是 : ,要么作为数字和数字,或数字和 : 之间的分隔符,所以在确定一个整体区域(就是恰好表示着一个数字的区域)时,要注意对应的4列是哪4列
  
  对于0这种第4行没有的,要尤其注意,在(X的个数 + X的位置 共同结合判断数字)的情况下,注意不要错误地把第5行当第4行了,此处很容易出错
*/



#include <iostream>
using namespace std;
char a[10][25];

int find(int x, int y) //统计1-7行(数组中是 0-6行)中,x列到y列的X的个数(包含x和y),并通过X的个数和X的分布,来找出这个范围的格点和X组成的答案,究竟是表示了什么数字 
{
	int ans = 0;
	for (int i = 0; i < 7; i++)
	for (int j = x; j <= y; j++) 
	if (a[i][j] == 'X') ans++;
	
	switch(ans) //以下几种ans只有一种可能,直接返回即可 
	{
		case 4: return 1;
		case 6: return 7;
		case 8: return 4;
		case 14: return 8;
		case 10: //ans为10的情况有3种,找到它们的LED图案之间的区别,根据区别确定到底表示哪个数字即可 
		if (a[4][x] == 'X') return 2;
		if (a[1][x] == 'X') return 5;
		return 3;
		case 12://ans为12的情况有3种,找到它们的LED图案之间的区别,根据区别确定到底表示哪个数字即可 
		if (a[4][x] == '.') return 9;
		if (a[1][y] == '.') return 6;
		return 0;
	}
//	return -1;
}

int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		for (int i = 0; i < 7; i++) cin >> a[i];
		cout << find(0, 3) << find(5, 8) << ":" << find(12, 15) << find(17, 20) << endl;
		//每个数字其实仅仅只占4个列,每个数字对应的是哪4列,可以从样例输入的格式中找到规律,就相当于传入一个恰好的区域,分离出这个区域代表的数字 
	}
	return 0;
}


原文地址:https://www.cnblogs.com/mofushaohua/p/7789532.html