第四届蓝桥杯省赛 C++ B组 - 带分数

简介: 第四届蓝桥杯省赛 C++ B组 - 带分数

问题描述


100 可以表示为带分数的形式:100=3+69258/714

还可以表示为:100=82+3546/197

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

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


输入格式

一个正整数。


输出格式

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


数据范围

1≤N<106


输入样例1:

100

输出样例1:

11

输入样例2:

105

输出样例2:

6


暴力法

#include <bits/stdc++.h>
using namespace std;
int n;
const int N = 10;
int res[N]; //存储结果
bool st[N]; //表示元素是否用过
int cnt = 0;
//计算每一段的总数
int calc(int l, int r) {
  int num = 0;
  for (int i = l; i <= r; i++) {
    num = num * 10 + res[i];
  }
  return num;
}
//将全排列的数组分成三段进行判断
void dfs(int k) {
  if (k == 9) {
    for (int i = 0; i < 7; i++) {
      for (int j = i + 1; j < 8; j++) {
        int a = calc(0, i);
        int b = calc(i + 1, j);
        int c = calc(j + 1, 8);
        if (a * c + b == n * c) //c++中除法是整除,所以要转换为乘法
          cnt++;
      }
    }
    return;
  }
  //进行全排列
  for (int i = 1; i <= 9; i++) {
    if (!st[i]) {
      st[i] = true;
      res[k] = i;
      dfs(k + 1);
      st[i] = false;
    }
  }
}
int main() {
  cin >> n;
  dfs(0);
  cout << cnt << endl;
  return 0;
}


暴力法(内置函数)

next_permutation() 蓝桥杯允许使用

#include<bits/stdc++.h>
using namespace std;
int n;
const int N=10;
int res[N]; //存储结果
int cnt=0;
//计算每一段的总数
int calc(int l,int r)
{
    int num=0;
    for(int i=l;i<=r;i++)
    {
        num=num*10+res[i];
    }
    return num;
}
int main()
{
    cin>>n;
    for(int i=0;i<9;i++)
        res[i]=i+1;
    do{
        for(int i=0;i<7;i++)
        {
            for(int j=i+1;j<8;j++)
            {
                int a=calc(0,i);
                int b=calc(i+1,j);
                int c=calc(j+1,8);
                if(a*c+b==n*c)
                    cnt++;
            }
        }
    }while(next_permutation(res,res+9));  //调用函数进行全排列
    cout<<cnt<<endl;
    return 0;
}


优化


先枚举 a ,再枚举 c ,直接通过 a 和 c 求出 b ,就不用再枚举 b 了。然后判断 b 是否满足要求,如果 b 中的每一位都没有被 a 和 c 所用过并且 1 到 9 都被已经用过了,则满足要求,答案总数加 1。


举个例子,假设 a 枚举到了 82,然后枚举 c,而 c 枚举到了 3456,则去计算 b,根据公式推导,b 等于 n*c-a*c,从而算出 197。接下来就进行判断,首先 abc 都不能为 0 这是肯定的,然后需要判断 b 是否用了剩下没有用过的数字,如果出现了 a 和 c 中的数字则不满足条件,并且 b 要将剩下没用过的数字全部用上才满足条件。



#include <bits/stdc++.h>
using namespace std;
const int N = 10;
int n, ans = 0;
bool st[N], backup[N];
//判断是否满足条件
bool check(int a, int c) {
    //计算b
    //这里需要long long是因为防止n为10的6次方时与c相乘后爆int,导致b为负数,x也会为负数
    //x为负数的话,backup就会数组越界,所以要加long long
  long long b = n * (long long)c - a * c;
  //a,b,c都不能为0
  if (!b || !a || !c)
    return false;
  //因为原状态数组不能改变,为了后续判断,就新建一个状态数组用于判断
  memcpy(backup, st, sizeof(st));
    //判断b中的每一位数字
  while (b) {
    int x = b % 10;
    if (!x || backup[x])
      return false;
    b /= 10;
    backup[x] = true;
  }
  //判断是否1-9都使用过
  for (int i = 1; i <= 9; i++) {
    if (!backup[i])
      return false;
  }
  return true;
}
//枚举c
void dfs_c(int x, int a, int c) {
  if (x > 9)
    return;
  if (check(a, c))
    ans++;
  for (int i = 1; i <= 9; i++) {
    if (!st[i]) {
      st[i] = true;
      dfs_c(x + 1, a, c * 10 + i);
      st[i] = false;
    }
  }
}
//枚举a
void dfs_a(int x, int a) {
  if (a >= n)
    return;
  if (a)
    dfs_c(x, a, 0);
  for (int i = 1; i <= 9; i++) {
    if (!st[i]) {
      st[i] = true;
      dfs_a(x + 1, a * 10 + i);
      st[i] = false;
    }
  }
}
int main() {
  cin >> n;
  dfs_a(0, 0);
  cout << ans << endl;
  return 0;
}
目录
相关文章
|
1月前
|
算法 测试技术 C++
【动态规划算法】蓝桥杯填充问题(C/C++)
【动态规划算法】蓝桥杯填充问题(C/C++)
|
1月前
|
人工智能 算法 BI
第十四届蓝桥杯省赛大学C组(C/C++)三国游戏
第十四届蓝桥杯省赛大学C组(C/C++)三国游戏
|
1月前
|
人工智能 C++
第十四届蓝桥杯省赛大学B组(C/C++)整数删除
第十四届蓝桥杯省赛大学B组(C/C++)整数删除
|
1月前
|
机器学习/深度学习 算法 关系型数据库
第十五届蓝桥杯C++B组省赛
第十五届蓝桥杯C++B组省赛
82 14
|
1月前
|
算法 C++
2022年第十三届蓝桥杯大赛C/C++语言B组省赛题解
2022年第十三届蓝桥杯大赛C/C++语言B组省赛题解
37 5
|
6月前
|
算法 测试技术 C++
小唐开始刷蓝桥(八)2013年第四届C/C++ B组蓝桥杯省赛真题
小唐开始刷蓝桥(八)2013年第四届C/C++ B组蓝桥杯省赛真题
|
6月前
|
算法 C++ 数据格式
小唐开始刷蓝桥(七)2014年第五届C/C++ B组蓝桥杯省赛真题
小唐开始刷蓝桥(七)2014年第五届C/C++ B组蓝桥杯省赛真题
|
6月前
|
数据安全/隐私保护 C++
小唐开始刷蓝桥(九)2012年第三届C/C++ B组蓝桥杯省赛真题
小唐开始刷蓝桥(九)2012年第三届C/C++ B组蓝桥杯省赛真题
|
1天前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
13 2
|
7天前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
33 5