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

[蓝桥杯 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;
}

相关推荐

  1. 【[ 2013 B] 带分数

    2024-01-31 07:10:06       16 阅读
  2. P8597 [ 2013 B] 翻硬币

    2024-01-31 07:10:06       38 阅读
  3. P8597 [ 2013 B] 翻硬币

    2024-01-31 07:10:06       15 阅读
  4. P8597 [ 2013 B] 翻硬币

    2024-01-31 07:10:06       14 阅读
  5. P8682 [ 2019 B] 等差数列

    2024-01-31 07:10:06       26 阅读
  6. P8661 [ 2018 B] 日志统计

    2024-01-31 07:10:06       35 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-31 07:10:06       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-31 07:10:06       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-31 07:10:06       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-31 07:10:06       18 阅读

热门阅读

  1. 网站分享(实用)

    2024-01-31 07:10:06       42 阅读
  2. NetCore iText7 根据PDF模板 导出PDF

    2024-01-31 07:10:06       35 阅读
  3. P8655 [蓝桥杯 2017 国 B] 发现环

    2024-01-31 07:10:06       37 阅读
  4. 最大公约数(左右区间问题)

    2024-01-31 07:10:06       33 阅读
  5. 深入理解并测试HttpResponse —— 关键知识和实践

    2024-01-31 07:10:06       29 阅读
  6. STM32——点灯

    2024-01-31 07:10:06       31 阅读
  7. vue中nextTick()

    2024-01-31 07:10:06       34 阅读
  8. Vue2:请求接口的两种方式axios和vue-resource

    2024-01-31 07:10:06       38 阅读
  9. [GN] DP学习笔记板子

    2024-01-31 07:10:06       32 阅读