首页 > 其他分享 >洛谷--【P1618】三连击升级版题解 排列枚举+循环枚举+stl

洛谷--【P1618】三连击升级版题解 排列枚举+循环枚举+stl

时间:2022-11-07 23:01:01浏览次数:39  
标签:连击 数字 int 题解 三位数 枚举 allocate include

题目描述

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

输入格式

三个数,A,B,C。

输出格式

若干行,每行 3 个数字。按照每行第一个数字升序排列。

输入输出样例

输入 #1
1 2 3
输出 #1192 384 576
219 438 657
273 546 819
327 654 981

题意解析:
根据题目要求不难发现题目想让我们在1-9九个数字数字中选择数字随机组合成三个数字使其比例成A:B:C,这样的三个不同的三位数组成一组数,把满足条件的所有组输出。三个数字一行。
下面通过代码来实现。
解法一(排列枚举+stl)
全ac代码如下:

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int a[10];
int main(){
    long long A,B,C,x,y,z;
    cin>>A>>B>>C;int cnt=0;
    for(int i=1;i<=9;i++){
        a[i]=i;
    }
    do{
        x=a[1]*100+a[2]*10+a[3];
        y=a[4]*100+a[5]*10+a[6];
        z=a[7]*100+a[8]*10+a[9];
        if(x*B==y*A&&y*C==z*B){
            printf("%lld %lld %lld\n",x,y,z);
            cnt++;
        }
    }while(next_permutation(a+1,a+10));
    if(!cnt) cout<<"No!!!";
}

浅析代码:顺着题目意思来我们可以把所有的符合条件的三位数进行枚举,再加上一个条件判断是否成比例即可。这里介绍stl标准库中很好用的一个标准函数next_permutation(start,end),其功能就是在[start,end)数组中产生严格的下一个字典序排列。因此我们可以初始化一个长度为10的数组,通过遍历将所有三位数枚举出来。这样再通过条件判断后就可以得到最后的答案了。

解法二:子集枚举

代码如下:

#include<iostream>
 using namespace std;
 #include<cstdio>
 #include<algorithm>
 #include<cstring>
 int b[10];
 bool check(int a,int b,int c);
 void allocate(int a);
 bool check(int x,int y,int z){
 memset(b,0,sizeof(b));
 if(y>999||z>999) return 0;
 allocate(x);allocate(y);allocate(z);
 for(int i=1;i<=9;i++){
 if(!b[i]) return 0;
 }
 return 1;
 }
 void allocate(int a){//将每一位数分配到桶中
 b[a%10]=1;
 b[a/10%10]=1;
 b[a/100]=1;
 }
 int main(){
 int A,B,C,i,y,z,cnt=0;cin>>A>>B>>C;
 for( i=123;i<=987;i++){
 if(i*B%A||i*C%A) continue;//先找到数i
 y=i*B/A,z=i*C/A;//再确定按比例分配的另外两个
 if(check(i,y,z))
 printf("%d %d %d\n",i,y,z),cnt++;
 }
 if(!cnt) puts("No!!!");
 return 0;
 }

 浅析代码:总的来说,这段代码不够简洁,而且如果这题求的是多位数可能就会比较繁琐,并且我在洛谷平台提交这段代码测评的时候在新上传的用例中有一个案例re了。基于其它案例顺利通过以及这种做法所蕴含的思想,我们也对这段代码进行解析,仅供参考。首先可以确定三位数的范围在123-987之间,因此可以先遍历这些数字,找到第一个满足条件的数字,进而算出另外两个数字。但是由于这个范围内一定存在含有0的三位数字,所以要进行判断。因此将所得的三个数字x,y,z传入check函数中,在check函数中再将三位数进行分解,这里写的allocate函数,由于下标为零的数组未被赋值所以为零,这样便可以区分0和非0数,检查若为真则计数器加一否则输出No!!!,最后得出正确答案。

 

 

标签:连击,数字,int,题解,三位数,枚举,allocate,include
From: https://www.cnblogs.com/curtain-cpp/p/16867826.html

相关文章

  • 枚举
    1.使用枚举创建1个新的数据类型来达到限定取值.;语法格式:enum新类型名称{限定取值1,限定取值2,限定取值3,....};enumDirection{East,South,west,North};表示新创建了1个数据类......
  • 【题解】CSP-J2022
    CSP-J2022题解/Limie T1.乘方 简要题意:给定a,b,求a^b(a^b表示a的b次方)是否大于10^9,大于输出-1,小于等于输出a^b。分析:此题直接枚举1~b会超时,故考虑用位数判断大小,a^b......
  • BUUCTF [ACTF新生赛2020]SoulLike题解(非爆破)
    查壳发现无壳。   IDA检查main函数显然先检查了输入是否以actf{开头进入sub_83A无法进入 点不进去是因为IDA限制了解析函数的长度,可以修改IDA下cfg......
  • git 问题解决
    1.fatal:theremoteendhungupunexpectedlygitconfig--globalhttp.postBuffer104857600其他方案:gitconfig--globalpack.windowMemory100mgitconfig-......
  • 【题解】codeforces 1746B Rebellion
    题意:给定一个只包含0和1的数组a,可以对a进行以下操作:选定两个下标不同的元素ai和aj,将ai加到aj上,再从数组中删除ai。问最少操作多少次,可以让数组a变成单调非下降子序列(即ai......
  • 常用枚举
    /**Copyright1999-2021AlibabaGroupHoldingLtd.**LicensedundertheApacheLicense,Version2.0(the"License");*youmaynotusethisfileexceptinc......
  • CSP-S2022题解(T4待填)
    闲话\(\huge{寄}\)\(\text{T1}\)极限脑抽,删掉暴搜打错解,\(70pts\to0pts\);\(\text{T2}\)洛谷\(100pts\)但\(\infin\)\(40pts\),很慌;\(\text{T3}\)差点想到正......
  • 在 flutter 中使用枚举的技巧
    在flutter中使用枚举的技巧前言例如,不管是谁在Kotlin之后,再开发Dart都对它带来的种种限制感到失望。其中之一是枚举类。单独使用枚举值是可以的,但是还有别的吗?你......
  • 2022CSP-S题解
    这次是我第一次参加\(CSP-J/S\),所以我决定口胡一下这几道题目,由于\(J\)组过于简单,就不再叙述,如有问题请私信我\(/oh/oh/oh\)假期计划(holiday)我们可以先进行\(n\)......
  • 洛谷 P3951 [NOIP2017 提高组] 小凯的疑惑 题解
    LuoguP3951[NOIP2017提高组]小凯的疑惑题解注:设\(A,B\)是两个集合,则\(A\timesB\)表示\(A\)与\(B\)的笛卡儿积(直积)。笛卡儿积的定义为\(S\timesM:=\{(s......