1. 程式人生 > >網易互娛2017實習生招聘線上筆試第一場-1電子數字

網易互娛2017實習生招聘線上筆試第一場-1電子數字

http://hihocoder.com/contest/ntest2016spring1/problem/1

時間限制:10000ms 

單點時限:1000ms 

記憶體限制:256MB 
描述 
電子數字在生活中很常見,而許多的電子數字是由LED數碼管制作而成。數字LED數碼管一般由7個發光二極體封裝在一起,組成’8’字型,引線在內部連線完成。如下圖所示,我們可以對每個發光管進行編碼從1到7。而數字0到數字9可以由這七根發光管的亮暗來表示。


假設我們現在有從左到右排列好的K個LED數碼管,並且我們已知每個數碼管當前有哪些編號的二極體是亮著的,另外剩餘的二極體由於某些原因,我們並不清楚它們的亮暗情況。由於已經有部分二極體是確定亮著的,所以每個LED數碼管能表示的數字範圍會有所縮小,譬如假設1號二極體已經確定是亮著的狀態,那麼這個LED數碼管就不能表示數字1和4。

我們想知道的是,給定一個數N,在這K個LED數碼管的當前亮暗的狀態下,所有可能表示的數中,比N小的數有多少個。

注意,前導0是必須的,假設有4個數碼管的話,’0000’表示0,’0123’表示123,即每個數的表示方法唯一。

樣例輸入

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

乍一看還以為要數位dp,後發現其實只要直接暴力,思路比較直接的題目,只是讀入時要稍微注意一下

#include<iostream>
#include<vector>
#include<string.h>
using namespace std;
typedef long long ll;
#define rep(i,n) for(int i=0;i<n;i++)
#define mst(k,j) memset(k,j,sizeof(k))
int kmap[8];
int pox[7]={1,10,100,1000,10000,100000,1000000};
int h,ans;
int res;
int k,n;
vector<int> vlist[6];

void init(){   //其實是先馬上秒寫了個小程式把幾個二進位制轉換成了十進位制
	kmap[1]=1005; // 1111101101
	kmap[2]=881;  // 1101110001
	kmap[3]=927;  // 1110011111
	kmap[4]=892;
	kmap[5]=325;
	kmap[6]=1019;
	kmap[7]=1005;
}

void dfs(int u){
	if(u==k){
		if(res<n)
			ans++;
		return;
	}
	rep(i,vlist[u].size()){
		res+=(vlist[u][i]*pox[k-u-1]);
		dfs(u+1);
		res-=(vlist[u][i]*pox[k-u-1]);
	}
}

int main()
{
	init();
	int T;
	cin>>T;
	char c;
	int has[6];
	while(T--){
		ans=0;
		cin>>k>>n;
		rep(i,6)
			vlist[i].clear();
		c=getchar();
		rep(i,k){
			while(c=='\n'||c==' '){
				c=getchar();
			}
			has[i]=kmap[c-'0'];
			c=getchar();
			while(c!='\n'){
				if(c>='0'&&c<='9')
					has[i]&=(kmap[c-'0']);
				c=getchar();
			}
			h=1;
			rep(j,10){
				if(h&has[i]){
					vlist[i].push_back(j);
				}
				h=h<<1;
			}
		}
		dfs(0);
		cout<<ans<<endl;
	}
}