题一 电子数字

简介:

一、题目

时间限制: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);
        }
    }
}
相关文章
|
5月前
|
传感器 监控 安全
eFuse电子保险丝
热保险丝作为一种基本的电路保护器件,已经成功使用了150多年。热保险丝有效可靠、易用,具有各种不同的数值和版本,能够满足不同的设计目标。然而,对于寻求以极快的速度切断电流的设计人员来说,热保险丝不可避免的缺点就是其自复位能力,以及在相对较低的电流下的工作能力。对于这些设计人员来说,电子保险丝(通常用eFuse或者e-Fuse表示)是一种很好的解决方案,有时还可以取代热保险丝,但通常是对热保险丝功能的补充。 eFuse基于一个简单概念,即通过测量已知电阻器上的电压来检测电流,然后在电流超过设计限值时,通过场效应晶体管(FET)切断电流。eFuse具有热保险丝无法实现特性、灵活性和功能。 本文
eFuse电子保险丝
|
测试技术
大额数字转节权位
大额数字转节权位
62 0
|
7月前
|
传感器 监控 安全
eFuse电子保险丝,需要了解的技术干货来啦
电子保险丝(eFuse)作为热保险丝的升级版,提供更快的反应速度(微秒至纳秒级)、低电流操作、可复位功能、反向电流和过压保护等优势。它们常用于需要快速保护的场景,如热插拔、汽车应用、PLC和电池管理。eFuse可以选择锁定或自动重启模式,根据应用需求调整。虽然可以使用分立组件构建基本的eFuse,但完整的IC解决方案更紧凑、稳定且功能丰富,通常包含多种保护特性,并已通过安全认证,适用于USB终端、笔记本电脑、服务器、可穿戴设备等多种应用。
202 4
|
8月前
|
安全 区块链 数据安全/隐私保护
区块链技术在数字版权保护中的应用
【2月更文挑战第9天】数字版权保护一直是一个备受关注的话题,随着互联网的普及,数字作品的复制、传播和盗版现象层出不穷。而区块链技术的出现为数字版权保护提供了新的解决方案。本文将探讨区块链技术在数字版权保护中的应用,并分析其优势和未来发展趋势。
|
开发框架 Rust 前端开发
金牛座与电子#137
金牛座与电子#137
112 0
通过身份证号码判断是否已成年
通过身份证号码判断是否已成年
194 0
|
BI 流计算
“电子“ ”“”哪里有
“电子“ ”“”哪里有此外,为了帮助大家更加深入了解EMR StarRocks,我们推出了EMR StarRocks 白皮书,供各位小伙伴学习参考,免费下载! 白皮书下载:https://developer.aliyun.com/ebook/7585 内容一览表: ? StarRocks 新?代极速全场景 MPP 数据仓库 ? StarRocks 简介 ? StarRocks 架构 ? StarRocks 特性 ? StarRocks ?态与?具 ? 数据迁移 ? 数据摄? ? 湖仓?体 ? StarRocks X Flink ?态 ? StarRocks 场景解决?案 ? 固定报表业务 ?
|
传感器
可随身携带的电子乐队
可随身携带的电子乐队
可随身携带的电子乐队
|
Oracle 关系型数据库
企业数字服务
本文研究全球及中国市场企业数字服务现状及未来发展趋势,侧重分析全球及中国市场的主要企业,同时对比北美、欧洲、中国、日本、东南亚和印度等地区的现状及未来发展趋势
|
存储 缓存 自然语言处理
数字政府 | 相关产品5
本文介绍了数字政府的相关产品,智能语音交互和混合云存储阵列.
数字政府 | 相关产品5