题一 电子数字

简介:

一、题目

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

描述

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

这里写图片描述

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

digit.jpg

用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 ≤ N ≤ 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

分析:这题是一道相对思路直观的题目,但是后面处理比 N 小的数,是可以转换为排列组合的数学问题解的。当然这样就需要判断是不是相等,如果相等就继续深入。

二、code

排列法:

#include <iostream>
#include <string>
#include <math.h>

using namespace std;

int res[12][12];
int digitCnt[6] ={0}; //该位可行计数
int miniCnt[6] = {0}; //该位比之小的
int equalCnt[6] = {0}; //是否和所比数当位有相等

int manyDigit(int a) {

    int cnt = 1;
    while ( a/=10 ) {
        ++cnt;
    }

    return cnt;
}

//get特定位数
int getDigit(int a, int n) {

    int p = pow(10,n-1);
    return (a/p)%10;
}

void work(int &resCnt,int deep,int n) {

    if(deep == n) { //递归结束条件
        return;
    }

    if ( equalCnt[deep] ) { //如果可相等

        work(resCnt,deep+1,n);
        int tmpCnt = miniCnt[deep];
        for (int i=deep+1;i<n;++i)
            tmpCnt*=digitCnt[i];

        resCnt += tmpCnt;
    }else {

        int tmpCnt = miniCnt[deep];
        for (int i=deep+1;i<n;++i)
            tmpCnt*=digitCnt[i];

        resCnt += tmpCnt;
    }
}

int main() 
{
    freopen("input.txt","r",stdin);

    int LED[10][8]={
         0,1,1,1,0,1,1,1 //0
        ,0,0,0,1,0,0,1,0 //1
        ,0,1,0,1,1,1,0,1 //2
        ,0,1,0,1,1,0,1,1 //3
        ,0,0,1,1,1,0,1,0 //4
        ,0,1,1,0,1,0,1,1 //5
        ,0,1,1,0,1,1,1,1 //6
        ,0,1,0,1,0,0,1,0 //7
        ,0,1,1,1,1,1,1,1 //8
        ,0,1,1,1,1,0,1,1 //9
    };

    int T;
    cin>>T;

start:
    while (T--) {

        //init
        for (int i=0;i<12;++i) {
            for (int j=0;j<12;++j) {
                res[i][j] = 1;
            }
        }

        memset(digitCnt,0,sizeof(digitCnt));
        memset(miniCnt,0,sizeof(miniCnt));
        memset(equalCnt,0,sizeof(equalCnt));

        int K;
        cin>>K;
        int N;
        cin>>N;

        getchar();
        for (int i=0;i<K;++i) {

            while (1){
                char tmp;
                tmp = getchar();

                if(tmp == ' ')
                    continue;

                if(tmp=='\n')
                    break;

                for (int j=0;j<=9;++j) { //0-9个数字

                    if( 0 == LED[j][tmp-48] )
                        //与某个数字j不吻合
                        res[i][j] = 0; //此位不能为j
                }
            }
        }

        //输入完毕,得出res可以为的数字
        //判断N是几位数
        int highdigit = manyDigit(N);

        //前导0
        for (int i=0;i<K-highdigit;++i) {
            if( res[i][0] != 1 ) {
                //错误
                cout<<"0"<<endl;
                goto start;
            }
        }

        //N最高位,是否比之小的
        int tmpDigit = getDigit(N,highdigit);
        int tmpFlag = 0;
        for (int i=0;i<=tmpDigit;++i) {
            if( res[K-highdigit][i] == 1 ) {
                tmpFlag = 1;
                break;
            }
        }
        if (tmpFlag == 0) {
            //错误
            cout<<"0"<<endl;
            goto start;
        }

        for (int i=K-highdigit;i<K;++i) {

            for(int j=0;j<=9;++j) {
                if(res[i][j] == 1) {
                    digitCnt[i]++;
                    if( j<getDigit(N,K-i) )
                        miniCnt[i]++;

                    else if(j == getDigit(N,K-i))
                        equalCnt[i]++;
                }
            }
        }

        //计算个数
        int resCnt = 0;
        int deep = K-highdigit;
        work(resCnt,deep,K);

        cout<<resCnt<<endl;
        //system("pause");
    }//while(T--)

    return 0; 
}

暴力:

#include <iostream>
#include <vector>
using namespace std;

void getNum(vector<vector<int>> numList, int deep, int temp, vector<int> &totalNums);

int main(void)
{
    int deng[10][7] = { {1,1,1,0,1,1,1},//0
    {0,0,1,0,0,1,0},
    {1,0,1,1,1,0,1},
    {1,0,1,1,0,1,1},
    {0,1,1,1,0,1,0},
    {1,1,0,1,0,1,1},
    {1,1,0,1,1,1,1},
    {1,0,1,0,0,1,0},//7
    {1,1,1,1,1,1,1},
    {1,1,1,1,0,1,1}//9
    };

    int S_test; //测试点的个数
    int K_LED;    //K个LED数码管
    int compareNum; //给定每个测试点比较的数

    cin>>S_test;

    int *endAnswer = new int[S_test]; //输出结果

    for(int i=0;i<S_test;i++) //测试用例
    {
        cin>>K_LED>>compareNum; //K个LED数码管, 测试的数字
        cin.ignore(); //忽略上一行的换行符!!!

        vector<vector<int>>num_K_LED; //存储每个LED可能的数字

        for (int j=0;j<K_LED;j++) //多少LED数码管 就多少行
        {
            char eachLine[100]; //每行表示对应数码管已点亮的二极管的情况

            cin.getline(eachLine,100);//cin>>eachLine;      //每行

            int servenLight[7] = {0};   //单个LED的7个指示灯哪个亮
            int idx = 0; //数组下标
            for(int k=0;k<strlen(eachLine);k++) //每行转为数字
            {               
                if(eachLine[k]!=' ')
                {
                    servenLight[idx] = int(eachLine[k] - '0'); //取数字
                    idx++;
                    if(idx == 7)
                    {
                        break;
                    }
                }
            }

            vector<int > num_eachLED; //记录单个LED中servenLight[7]中亮的可能是哪些数字?
            for (int deng_i = 0; deng_i <10;deng_i ++) //循环0-9,符合的加入num_eachLED
            {
                bool rs = true;
                int idx = 0;

                while (servenLight[idx] !=0)  //所有亮的指示灯都在 这个数字中
                {
                    if(deng[deng_i][ servenLight[idx] -1] != 1)
                    {
                        rs = false;                     
                        break;
                    }
                    idx++;
                }
                if(rs)
                {
                    num_eachLED.push_back(deng_i);
                }                               
            }

            num_K_LED.push_back(num_eachLED);
        }


        vector<int> totalNums; //记录所有组合出来的数字
        int deep =0; 
        int temp =0;
        getNum(num_K_LED, deep, temp, totalNums);

        int count = 0;
        for (int totalNums_i = 0; totalNums_i < totalNums.size();totalNums_i++)
        {
            if(compareNum >= totalNums[totalNums_i])
            {
                count++;
            }
        }
        endAnswer[i] = count;
    }

    for(int i = 0; i<S_test; i++)
    {
        cout<<endAnswer[i]<<endl;
    }


    //system("pause");
    return 0;
}

void getNum(vector<vector<int>> numList, int deep, int temp, vector<int> &totalNums)
{
    if(deep < numList.size()-1)
    {
        for(int i=0; i < numList[deep].size(); i++)
        {
            int newInt = temp + numList[deep][i] * pow(10,numList.size()- deep -1);
            getNum(numList, deep+1, newInt,totalNums);
        }
    }
    else if(deep == numList.size()-1)
    {
        for(int i=0; i < numList[deep].size(); i++)
        {
            int newInt = temp + numList[deep][i] * pow(10,numList.size()- deep -1);
            totalNums.push_back(newInt);
        }
    }
}
相关文章
|
3天前
|
存储 监控 安全
智能家居安全:保护你的数字家园
在数字化浪潮中,智能家居成为现代生活不可或缺的一部分,带来便利的同时,也引入了新的安全隐患。本文将深入探讨智能家居系统的安全挑战,并提供实用的防护措施,帮助用户构建一个更安全的数字家园。
|
8天前
|
监控 安全 数据安全/隐私保护
智能家居安全:保护您的数字家园
在数字化时代,智能家居系统为我们的生活带来了便利,但同时也引入了新的安全隐患。本文将探讨智能家居面临的主要安全挑战,并提供实用的保护措施,以增强您家庭网络的防御能力。
|
20天前
|
安全 机器人 网络安全
智能家居安全:保护我们的数字生活
【8月更文挑战第23天】 随着科技的飞速发展,智能家居设备已经走入了千家万户。然而,这些便捷的设备也可能成为我们隐私与安全的隐患。本文将深入探讨智能家居带来的安全挑战,并分享一系列实用的防护措施,帮助我们在享受智能生活的便利的同时,确保个人数据的安全。
32 7
|
23天前
|
安全 数据安全/隐私保护 智能硬件
智能家居安全:如何保护你的数字家园
在数字化时代,智能家居设备为我们的生活带来了前所未有的便利。然而,随之而来的安全问题也不容忽视。本文将探讨智能家居面临的主要安全威胁,并提供实用的防护措施,帮助你打造一个更安全的数字家园。
|
27天前
|
安全 网络安全 数据安全/隐私保护
智能家居安全:保护你的数字生活
当智能家居成为现代生活的标配,我们享受着科技带来的便利。但同时,数据泄露、隐私侵犯的风险也悄然而至。本文将带你了解智能家居背后的安全挑战,并分享实用的防护技巧,确保你的数字生活既智能又安全。
|
1月前
|
安全 数据安全/隐私保护 网络虚拟化
智能家居安全:如何保护你的数字生活
在数字化时代,智能家居设备为我们的生活带来了便利,但同时也引发了隐私与安全的担忧。本文将深入探讨智能家居系统中潜在的安全风险,并提供实用的防护策略,帮助用户构建一个更加安全可靠的智能生活环境。
|
9月前
|
测试技术
大额数字转节权位
大额数字转节权位
41 0
|
3月前
|
传感器 监控 安全
eFuse电子保险丝,需要了解的技术干货来啦
电子保险丝(eFuse)作为热保险丝的升级版,提供更快的反应速度(微秒至纳秒级)、低电流操作、可复位功能、反向电流和过压保护等优势。它们常用于需要快速保护的场景,如热插拔、汽车应用、PLC和电池管理。eFuse可以选择锁定或自动重启模式,根据应用需求调整。虽然可以使用分立组件构建基本的eFuse,但完整的IC解决方案更紧凑、稳定且功能丰富,通常包含多种保护特性,并已通过安全认证,适用于USB终端、笔记本电脑、服务器、可穿戴设备等多种应用。
111 4
|
前端开发 API 图形学
3D技术在数字藏品中的应用
本文通过图文的方式详细介绍了在淘宝App中如何使用3D相关技术,优化淘宝App中的数字藏品的展示。从背景介绍、方案设计、模型预处理,模型处理、脚本操作等过过程出发来介绍,同时重点分析了其中的一些核心技术问题的解法。希望通过这篇文章,能够给初次接触 blender 和 unity 的前端开发同学有一定的启发和参考。
148 0
3D技术在数字藏品中的应用
数字农业软件
本文研究全球及中国市场数字农业软件现状及未来发展趋势,侧重分析全球及中国市场的主要企业,同时对比北美、欧洲、中国、日本、东南亚和印度等地区的现状及未来发展趋势