网易游戏实习笔试题

题目1 : 电子数字

时间限制: 10000ms
单点时限: 1000ms
内存限制: 256MB

描述

电子数字在生活中很常见,而许多的电子数字是由LED数码管制作而成。数字LED数码管一般由7个发光二极管封装在一起,组成'8'字型,引线在内部连接完成。如下图所示,我们可以对每个发光管进行编码从1到7。而数字0到数字9可以由这七根发光管的亮暗来表示。


对LED数码管的二极管进行编码

用LED数码管表示数字0-9

假设我们现在有从左到右排列好的K个LED数码管,并且我们已知每个数码管当前有哪些编号的二极管是亮着的,另外剩余的二极管由于某些原因,我们并不清楚它们的亮暗情况。由于已经有部分二极管是确定亮着的,所以每个LED数码管能表示的数字范围会有所缩小,譬如假设1号二极管已经确定是亮着的状态,那么这个LED数码管就不能表示数字1和4。

我们想知道的是,给定一个数N,在这K个LED数码管的当前亮暗的状态下,所有可能表示的数中,比N小的数有多少个。

注意,前导0是必须的,假设有4个数码管的话,'0000'表示0,'0123'表示123,即每个数的表示方法唯一。

输入

每个输入数据包含多个测试点。

第一行为测试点的个数 S ≤ 100。之后是 S 个测试点的数据。测试点之间无空行。

每个测试点的第一行为 K(1 ≤ K ≤ 5)和N(0 ≤ ≤ 109)。之后是K行,每行表示对应数码管已点亮的二极管的情况。每行至少包含一个数字,表示对应点亮的二极管的编号,即每个数码管至少有一根二极管是点亮的。二极管编号的范围保证在1到7之间,且每行无重复编号。

注意表示数码管点亮情况的每行数字之间以及行首行末之间可能存在冗余空格,每行的字符总长度不超过100。

输出

对于每个测试点,对应的结果输出一行,表示这K个数码管在当前状态下,所有可能表示的数中,比N小的数有多少个。

样例解释

第一个样例中,只有'020', '026', '028'符合要求。

第三个样例中,只有'000'符合要求。

样例输入
3
3 50
3  1
  1  4  5  
1   5  6 7
4 100
1 2 3
   4   5
6
  7  
1 1
  7
样例输出
3
0
1



#include "stdafx.h"

#include <vector>
#include <iostream>
#include <random>
#include <map>
#include <string>
using namespace std;
void fun(vector<vector<char>> &res, vector<string>& comb, string &str, int k, int s, vector<int>&ss);
int main()
{
	int s;
	int k, n;
	map<int, vector<int>> m;
	vector<int> v1 = {3,6};
	vector<int> v2 = {1,3,4,5,7};
	vector<int> v3 = {1,3,4,6,7};
	vector<int> v4 = {2,3,4,6};
	vector<int> v5 = {1,2,4,6,7};
	vector<int> v6 = {1,2,4,5,6,7};
	vector<int> v7 = {1,3,6};
	vector<int> v8 = {1,2,3,4,5,6,7};
	vector<int> v9 = {1,2,3,4,6,7};
	vector<int> v0 = {1,2,3,5,6,7};
	m.insert(make_pair(1,v1));
	m.insert(make_pair(2, v2));
	m.insert(make_pair(3, v3));
	m.insert(make_pair(4, v4));
	m.insert(make_pair(5, v5));
	m.insert(make_pair(6, v6));
	m.insert(make_pair(7, v7));
	m.insert(make_pair(8, v8));
	m.insert(make_pair(9, v9));
	m.insert(make_pair(0, v0));


	vector<vector<char>> res;
	cin >> s;
	while (s--)
	{
		cin >> k >> n;
		cin.ignore(); //忽略上一行的换行符!!! 
		for (int h = 0;h < k;h++)
		{
			char eachLine[10];
			vector<char> c;
			cin.getline(eachLine, 10);
			for (int i = 0;i < 10;i++)
			{
				int flag = 0;
				for (int k = 0;k < strlen(eachLine);k++)
				{
					if ((eachLine[k]!=' ')&&find(m[i].begin(), m[i].end(), (eachLine[k] - '0')) == m[i].end())
					{
						flag = 1;
						break;
					}
				}
				if (flag == 0)
					c.push_back(i+'0');
			}
			res.push_back(c);
		}
		vector<string> comb;
		vector<int>ss(10, 0);
		string str;
		fun(res, comb, str, k, 0, ss);
		int count = 0;
		for (int i = 0;i < comb.size();i++)
		{
			if (stoi(comb[i]) < n)
				count++;
		}
		cout << count << endl;
	}




	int a;
	cin >> a;
	return 0;
}

//回溯法求所有排列情况
void fun(vector<vector<char>> &res,vector<string>& comb,string &str,int k, int s, vector<int>&ss)
{
	if (s == k)
	{
		comb.push_back(str);
	}
	else
	{
		for (int i = ss[s];i < res[s].size();i++)
		{
			str =str+ res[s][i] ;
			ss[s]++;
			fun(res, comb, str, k, s+1,ss);
			ss[s]--;
			str.pop_back();
		}
	}
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值