1 条题解

  • 1
    @ 2025-8-22 11:56:22

    本题由(NOIP1998 普及组 T1)三连击 改编而来.(建议先AC三连击原题再来尝试本题)

    ————————————————————

    三连击原题题目:

    将 1,2,…,9 共 9 个数分成 3 组,分别组成 3 个三位数,且使这 3 个三位数构成 1:2:3 的比例,试求出所有满足条件的 3 个三位数 (本题没有思路的同学,可以先按照原题目尝试思考)

    ————————————————————

    原题目解法:

    暴力枚举所有三位数(其实从165~494就行,即987/6*1~987/6 *3)

    由枚举的数作为第一个数字,按比例换算出另外两个数

    再判断检查三个数是否合法(即1~9都只出现了一次且不为四位数)

    ————————————————————

    本题解法:

    本题把原本固定的1:2:3的比例变为输入而来

    在上一题中,我们枚举第一个数字,因为第一个数字的相对比例为1,但此处则不一定为1

    所以我们定义一个"基准数"作为枚举对象(13~329,即123/9~987/3),由"基准数"按比例换算出三个数,再判断检查是否合法即可

    无解情况处理:

    定义一个布尔值,表示有无解(默认为0),输出时赋值为1 枚举完数字后判断有无解,无则输出"No!!!"

    ————————————————————

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    int x,y,z,a,b,c;//a,b,c为比例;x,y,z为答案
    bool k[10],f;//k为各数字使用情况;f为有无解
    bool df(int n){//判断此数字是否合法
    	int k1,k2,k3;//各个位上的数字
    	k1=n%10;//个位
    	k2=n%100-k1;k2/=10;//十位
    	k3=n-k1-k2;k3/=100;//百位
    	if((k1==0)||(k2==0)||(k3==0))return 1;//特判零
    	if(k[k1])return 1;//使用过
    	k[k1]=1;//标记为使用过
    	if(k[k2])return 1;
    	k[k2]=1;
    	if(k[k3])return 1;
    	k[k3]=1;
    	return 0;
    }
    int main(){cin>>a>>b>>c;
        for(int n=13;n<=329;n++){//枚举基准数
    		x=n*a;y=n*b;z=n*c;//由基准数按比例换算出三个数字
    		if(x>987||y>987||z>987)continue;//大于987则必定非法
    		for(int i=1;i<=9;i++)k[i]=0;//初始化每个数字的使用情况
    		if(df(x)||df(y)||df(z))continue;//非法则跳过
    		printf("%d %d %d\n",x,y,z);f=1;//有解
    	}if(!f)printf("No!!!");//判断有无解
    	return 0;
    }```
    • 1

    信息

    ID
    449
    时间
    1000ms
    内存
    128MiB
    难度
    10
    标签
    递交数
    17
    已通过
    1
    上传者