洛谷P8599 [蓝桥杯 2013 省 B] 带分数

news/2024/7/15 17:07:22 标签: 蓝桥杯, 图论, 算法

[蓝桥杯 2013 省 B] 带分数

题目描述

100 100 100 可以表示为带分数的形式: 100 = 3 + 69258 714 100 = 3 + \frac{69258}{714} 100=3+71469258

还可以表示为: 100 = 82 + 3546 197 100 = 82 + \frac{3546}{197} 100=82+1973546

注意特征:带分数中,数字 1 1 1 ~ 9 9 9 分别出现且只出现一次(不包含 0 0 0)。

类似这样的带分数, 100 100 100 11 11 11 种表示法。

输入格式

从标准输入读入一个正整数 N ( N < 1 0 6 ) N(N<10^6) N(N<106)

输出格式

程序输出数字 N N N 用数码 1 1 1 ~ 9 9 9 不重复不遗漏地组成带分数表示的全部种数。

注意:不要求输出每个表示,只统计有多少表示法!

样例 #1

样例输入 #1

100

样例输出 #1

11

样例 #2

样例输入 #2

105

样例输出 #2

6

提示

原题时限 3 秒, 64M。蓝桥杯 2013 年第四届省赛

暴力做法

要保证1~9这每个数都要出现,且仅出现一次,可以联想到AcWing 842. 排列数字该暴力解法,就是在排列数字的基础上,将9个数的自由排列先求出来,然后根据式子
n = a + b c n = a + \frac{b}{c} n=a+cb
的基础上,枚举每一个a, b的位数,双重循环,c的位数可以由9 - a - b求出,通过get_value函数将每个求出来,再验证式子是否正确,由于c++中的除法是取整后的结果,所以要转换成乘法在进行验证。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <math.h>
using namespace std;

const int N = 15;

int path[N];//九个数的自由排列结果
bool st[N];
int n, res = 0;

int get_value(int k, int c){// k为起始下标,c为总位数
    int res = 0;
    for (int i = 0; i < c; i ++){
        res += path[k + i] * pow(10, c - i - 1);
    }
    return res;
}

void dfs(int k){
    if (k == 9){
        for (int i = 1; i < 9; i ++){
            int a = get_value(0, i);
            if (a > n) break;//a如果大于n就一定等式不成立,提前剪枝
            for (int j = 1; j < 9 - i; j ++){
                int k = 9 - i - j;
                if (k <= 0) break;
                else{
                    int b = get_value(i, j);
                    int c = get_value(i + j, k);
                    
                    if (n * c == a * c + b ){//这里必须要变形成乘法形式,因为除法是取整除法会导致答案过多
                        res ++;
                    }
                }
            }
        }
        return;
    }
    
    for (int i = 1; i <= 9; i ++){
        if (!st[i]){
            st[i] = true;
            path[k] = i;
            dfs(k + 1);
            st[i] = false;
        }
    }
}

int main(){
    scanf("%d", &n);
    
    dfs(0);
    printf("%d", res);
    return 0;
}

在这里插入图片描述
要开 O 2 O_2 O2优化,不然超过1s了TLE

嵌套dfs

首先通过传入参数的形式将a, c的值求出来,减少了多次求的运算过程,通过先dfs_a, 中嵌套dfs_c,枚举所有结果,用check进行剪枝,来加快处理速度。
b = n( 1 0 6 10^6 106) * c(10^6) 爆int( 1 0 10 10^{10} 1010)了,所以要用 l o n g l o n g long long longlong来存b

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 20;
typedef long long LL;

bool st[N], backup[N];
int n, res = 0;

bool check(int a, int c){//判断当前a, c是否满足题目的要求
    LL b = n * (LL)c - a * c;
    
    if (!a || !b || !c) return false; //当a, b, c为零时不满足,边界特判
    
    memcpy(backup, st, sizeof st);//由于b中的数字可能重复,所以需要改变st中的值判断重复,但这影响了st,所以要先复制
    while (b){//将b中的每个数字都抠出来
        int x = b % 10;
        b /= 10;
        if (!x || backup[x]) return false; 
        backup[x] = true;
    }
    for (int i = 1; i <= 9; i ++){
        if (!backup[i]) return false;
    }

    return true;
}

void dfs_c(int k, int a, int c){
    if(k == n) return;
    
    if (check(a, c)) res ++;//当前c不满足,也要接着后面代码找下一个c,不能return
    
    for (int i = 1; i <= 9; i ++){
        if (!st[i]){
            st[i] = true;
            dfs_c(k + 1, a, c * 10 + i);
            st[i] = false;
        }
    }
}

void dfs_a(int k, int a){
    if (a > n) return;
    dfs_c(k, a, 0);
    
    for (int i = 1; i <= 9; i ++){
        if (!st[i]){
            st[i] = true;
            dfs_a(k + 1, a * 10 + i);
            st[i] = false;
        }
    }
}

int main(){
    scanf("%d", &n);
    
    dfs_a(0, 0);//枚举到第几位,a的值为多少
    printf("%d\n", res);
    return 0;
}

http://www.niftyadmin.cn/n/5356697.html

相关文章

什么是国密算法?工业网关为什么要支持国密算法?

国密算法是由国家密码管理局制定并公布的通信加密/解密算法&#xff0c;因此被普遍称为“国密算法”&#xff0c;国密算法目前分为5类&#xff0c;分别是SM1、SM2、SM3、SM4和SM9&#xff0c;涵盖对称密钥算法、非对称密钥算法和哈希算法。 工业网关是应用于工业物联网的常见通…

STM32——感应开关盖垃圾桶

STM32——感应开关盖垃圾桶 1.定时器介绍 软件定时 缺点&#xff1a;不精确、占用CPU资源 void Delay500ms() //11.0592MHz {unsigned char i, j, k;_nop_();i 4;j 129;k 119;do{do{while (--k);} while (--j);} while (--i); }定时器工作原理 使用精准的时基&#xff…

WindTerm 安装使用教程

一、WindTerm 功能介绍 WindTerm 是一款 Github 上开源的 SSH 终端工具,它是完全可以比肩 MobaXterm 工具的。其支持的系统及功能如下: 功能支持: SSHTelnetShellTCPSerialSFTPCmdPowerShellGit二、WindTerm 官网下载 有两种获取方法: 方法一:windterm的github官方网址…

CGAL5.4.1 边塌陷算法

目录 1、使用曲面网格的示例 2、使用默认多面体的示例 3、使用丰富多面体的示例 主要对1、使用曲面网格的示例 进行深度研究 CGAL编译与安装CGAL安装到验证到深入_cgal测试代码-CSDN博客 参考资料CGAL 5.4.5 - Triangulated Surface Mesh Simplification: User Manual …

将 Quartz.NET 调度框架与 Stimulsoft Reports 结合使用

今天&#xff0c;我们将深入探讨软件开发的一种现代趋势 - 流程自动化&#xff0c;这自然是 Stimulsoft 产品中报表处理的一部分。在本文中&#xff0c;我们将讨论如何使用第三方调度程序自动执行与 Web 项目中的报告相关的任务。作为对报告执行操作的示例&#xff0c;我们考虑…

向上调整向下调整算法

目录 AdjustUp向上调整 AdjustDown向下调整 AdjustUp向上调整 前提是&#xff1a;插入数据之后&#xff0c;除去插入的数据其他的数据还是为堆 应用&#xff1a;插入数据。 先插入一个10到数组的尾上&#xff0c;再进行向上调整算法&#xff0c;直到满足堆。 性质&#xff1…

虹科方案|释放总线潜力:汽车总线离线模拟解决方案

导读&#xff1a;传统的ECU模拟工具通常需要依赖上位机软件来发起通信&#xff0c;这在离线场景和自动化产线中带来不便。为了应对这一挑战&#xff0c;虹科推出了创新的汽车总线离线模拟解决方案&#xff0c;基于PCAN-Router系列网关&#xff0c;通过内部可编程固件&#xff0…

【JAVA】Long类型返回到前端,精度丢失

一. 问题阐述 20位long类型的数字&#xff0c;从后端接口返回到前端后【四舍五入】 MYSQL端 &#xff08;1&#xff09;bigint (20) &#xff08;2&#xff09;具体某一条数据 JAVA端 &#xff08;1&#xff09;实体类 &#xff08;2&#xff09;服务类 &#xff08;3&…