zoukankan      html  css  js  c++  java
  • P1618 三连击(升级版)

    原题地址:https://www.luogu.com.cn/problem/P1618

    题目描述:将 1, 2,9 共 9 个数分成三组,分别组成三个三位数,且使这三个三位数的比例是 A:B:C,试求出所有满足条件的三个三位数,若无解,输出 No!!!

    输入格式:三个数,A,B,C

    输出格式:若干行,每行 3 个数字。按照每行第一个数字升序排列。

     

    一开始的思路是打表从一个存储123456789的数组里直接选数,保证选完的不再选(可以用一个bool数组存放“是否已选”),但我不会搜索、动态规划什么的,逻辑能力十分弱,这种解法真的想不出来。

    这里要感谢大佬 可耐滴小慕容 (主页->)https://www.luogu.com.cn/user/24663#main的题解,ta启发了我的新思路(我真的没抄袭复制!所有代码都是我自己写的!只是ta的思路启发了我!这应该不算抄袭吧!)

    可以直接枚举第一个数,根据比例算出来另外两个数,再进行判断!(这句话是大佬的知识产权)

    首先设计出判断数字位数和获取数字某一位的数字的函数,以备之后使用:

    int getCertainNumOfInt(int a,int num)//返回数字串a的第num位数(从右往左数)。
    {
        int ten=1,q;
        for(q=1;q<num;q++)
        {
            ten*=10;
        }
        int r=a/ten%10;
        return r;
    }
    
    int get_length(int a)//返回数字a的位数。
    {
        int leng=0;
        while(a)
        {
            a/=10;
            leng++;
        }
        return leng;
    }

    然后是存储1—9数字是否用过的数组:

    int p[10]={0,0,0,0,0,0,0,0,0,0};

    (p[0]纯属占位)

    然后,判断一个三位数本身是否重复的函数(自己就重复就肯定不对了)

    bool isNoRepeat(int a)
    {
        int ge=a%10;//个位数 
        int bai=a/100;//百位数 
        int shi=(a/10)%10;//十位数 
        if(ge==bai||ge==shi||bai==shi) return false;//只要有相同的数就不满足条件 
        else return true;
    }

    接着是判断三个三位数的数字是否互不重复:

    bool isAllNoRepeat(int a,int b,int c)
    {
        if(!(isNoRepeat(a)&&isNoRepeat(b)&&isNoRepeat(c))) return false;//只要自身重复了就不对
        else
        {
            for(int i=1;i<=3;i++)
            {
                p[getCertainNumOfInt(a,i)]++;
            }
            for(int i=1;i<=3;i++)
            {
                p[getCertainNumOfInt(b,i)]++;
            }
            for(int i=1;i<=3;i++)
            {
                p[getCertainNumOfInt(c,i)]++;
            }
        }
        for(int i=1;i<10;i++)
        {
            if(p[i]!=1)//有0代表有的数字没选,有大于一的数字代表有的数字选了多次,都不对
            {
                memset(p,0,sizeof(p));//别忘了原数组清零,供下一次使用
                return false;
            }
        }
        memset(p,0,sizeof(p));//别忘了原数组清零,供下一次使用
        return true;                
    }

    以下是main的第一版代码(不对的一版):

    int main()
    {
        int a,b,c;
        cin>>a>>b>>c;
        int x,y,z;//存放根据比例算出的三个三位数
        int tot=0;
        for(int i=100;i<=999;i++)
        {
            if(!isNoRepeat(i)) continue;//自己要不重复
            x=i;
            y=x/a*b;//潜在问题
            z=x/a*c;//潜在问题
            if(x<1000&&y<1000&&z<1000/*必须是三位数*/&&isAllNoRepeat(x,y,z))
            {
                cout<<x<<" "<<y<<" "<<z<<endl;
                tot++;
            }
        }
        if(!tot) cout<<"No!!!";//没有答案
        return 0;
    }

    注意到潜在问题了吗?可能有极特殊的情况,由于xyz的精度不高,可能算不出精确的三位数!最后,这种代码导致了一个监测点WA。

    第二版代码:

    int main()
    {
        int a,b,c;
        cin>>a>>b>>c;
        double x,y,z;
        int tot=0;
        for(int i=100;i<=999;i++)
        {
            if(!isNoRepeat(i)) continue;
            x=(double)i;
            y=x/(double)a*b;
            z=x/(double)a*c;
            if(x<1000&&y<1000&&z<1000&&isAllNoRepeat(x,y,z))
            {
                cout<<x<<" "<<y<<" "<<z<<endl;
                tot++;
            }
        }
        if(!tot) cout<<"No!!!";
        return 0;
    }

    double换取了更高的精度,算出的数字排除了特殊情况。全部AC!

    这个题让我学到了:1.换一种思路!方法总比困难多!

    2.用除法的时候要特别考虑精度(即用int还是double)

  • 相关阅读:
    CSS HACK:IE6、IE7、IE8、Firefox兼容性问题解决方案
    C# @符号的多种使用方法
    16个Javascript的Web UI库、框架及工具包
    【分享】20个很不错的UI图标集资源
    JQuery/AjaX/Javascript/DIV+CSS资源下载地址
    发个csdn泄露账户查询地址,没下数据库的童鞋来查一下自己
    【总结】CSS透明度大汇总
    C#综合揭秘——细说事务
    ASP.NET获取客户端、服务器端基础信息集合
    收集的网络上大型的开源图像处理软件代码(提供下载链接)
  • 原文地址:https://www.cnblogs.com/jiangyuechen/p/12261879.html
Copyright © 2011-2022 走看看