0 题目来源

acwing

1 涉及到的知识点

递归、全排列等

1.1 给定位数范围的全排列模板

  1. vector<int> vec;
  2. int test[10];
  3. void dfs(int u)
  4. {
  5. if (u > 3)//位数范围为1~3位
  6. return;
  7. for (int i = 0; i < vec.size(); i++)
  8. cout << vec[i] << ' ';
  9. cout << endl;
  10. for (int i = 1; i <= 9; i++)//1~9的数字
  11. {
  12. if (test[i] == 0)
  13. {
  14. test[i] = 1;
  15. vec.push_back(i);
  16. dfs(u + 1);
  17. vec.pop_back();
  18. test[i] = 0;
  19. }
  20. }
  21. }

1.2 确定位数的全排列模板

  1. vector<int> vec;
  2. int test[10];
  3. void dfs(int u)
  4. {
  5. if (u == 3)//确定输出3位
  6. {
  7. for (int i = 0; i < vec.size(); i++)
  8. cout << vec[i] << ' ';
  9. cout << endl;
  10. return;
  11. }
  12. for (int i = 1; i <= 9; i++)//1~9的数字
  13. {
  14. if (test[i] == 0)
  15. {
  16. test[i] = 1;
  17. vec.push_back(i);
  18. dfs(u + 1);
  19. vec.pop_back();
  20. test[i] = 0;
  21. }
  22. }
  23. }

1.3 逐位取出一个整数中的每一位模板

  1. while (num)
  2. {
  3. int temp = num % 10;//temp即为每一位
  4. b /= 10;
  5. }

2 题目描述

100可以表示为带分数的形式:image.png
还可以表示为:image.png
注意特征:带分数中,数字1∼9分别出现且只出现一次(不包含0)。
类似这样的带分数,100有11种表示法。

3 输入输出

输入格式:
一个正整数。
输出格式:
输出输入数字用数码1∼9不重复不遗漏地组成带分数表示的全部种数。
数据范围:
[题解]带分数 - 图3

4 样例

输入样例1:
100
输出样例1:
11
输入样例2:
105
输出样例2:
6

5 思路

本题需要分别取a、b、c,使其满足[题解]带分数 - 图4
上式可以变形为[题解]带分数 - 图5
因此,只要确定a、c,则b可以计算得出。
因此,可以通过两个嵌套的全排列(给定位数范围),对a、c的所有可能情况进行枚举,并计算相应的b,检测满足题意的情况个数,即得到答案。

6 代码

  1. #include<iostream>
  2. #include<cstring>
  3. long long ans, n;
  4. int test[10];
  5. int cpytest[10];
  6. using namespace std;
  7. bool check(long long b)
  8. {
  9. memcpy(cpytest, test, sizeof test);//容易遗漏,由于需要多次检测,而每次检测会对检测数组进行改变,因此在每次检测开始前需要对检测数组进行还原。
  10. while (b)
  11. {
  12. int temp = b % 10;
  13. b /= 10;
  14. if (temp == 0)
  15. return false;
  16. if (cpytest[temp] == 0)
  17. cpytest[temp] = 1;
  18. else
  19. return false;
  20. }
  21. for (int i = 1; i <= 9; i++)//容易遗漏,遍历cpytest,确保a、b、c覆盖1~9所有位
  22. {
  23. if (cpytest[i] == 0)
  24. return false;
  25. }
  26. return true;
  27. }
  28. void dfs_c(int u, long long a, long long c)
  29. {
  30. if (u > 9)
  31. return;
  32. long long b = n * (long long)c - a * c;
  33. if (a != 0 && c != 0 && b != 0 && check(b))
  34. ans++;
  35. for (int i = 1; i <= 9; i++)
  36. {
  37. if (test[i] == 0)
  38. {
  39. test[i] = 1;
  40. dfs_c(u + 1, a, c * 10 + i);
  41. test[i] = 0;
  42. }
  43. }
  44. }
  45. void dfs_a(int u, long long a)
  46. {
  47. if (a >= n)
  48. return;
  49. if(a)
  50. dfs_c(u, a, 0);
  51. for (int i = 1; i <= 9; i++)
  52. {
  53. if (test[i] == 0)
  54. {
  55. test[i] = 1;
  56. dfs_a(u + 1, a * 10 + i);
  57. test[i] = 0;
  58. }
  59. }
  60. }
  61. int main()
  62. {
  63. cin >> n;
  64. dfs_a(0, 0);
  65. cout << ans;
  66. return 0;
  67. }