0
点赞
收藏
分享

微信扫一扫

1209. 带分数

IT程序员 2022-02-05 阅读 68

ACwing的链接为https://www.acwing.com/problem/content/description/1211/icon-default.png?t=M0H8https://www.acwing.com/problem/content/description/1211/

100 可以表示为带分数的形式:100=3+69258714100=3+69258714

还可以表示为:100=82+3546197100=82+3546197

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

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

输入格式

一个正整数。

输出格式

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

数据范围

1≤N<1061≤N<106

输入样例1:

100

输出样例1:

11

输入样例2:

105

输出样例2:

6

代码为:

#include <bits/stdc++.h>

using namespace std;

const int N = 10;

int target;
int num[N];

int calc(int l, int r) {
  int res = 0;
  for (int i = l; i <= r; i++) {
    res = res * 10 + num[i];
  }
  return res;
}

int main() {
  cin >> target;
  for (int i = 0; i < 9; i++) {
    num[i] = i + 1;
  }
  int res = 0;
  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 == c * target) {
          ++res;
        }
      }
    }
  } while (next_permutation(num, num + 9));
  cout << res << '\n';
  return 0;
}

用了暴力破解,分成三段,依次列举,找到符合题意的。

res=res*10+num[i];

 这个是相当于加法进位,数组中每个元素都是单独一个个位数,然后比如说num[2]…num[3]num[2]…num[3],就看作是num[2]…num[3]num[2]…num[3]之间的这22个个位数连接成一个两位数对吧,组成的这个两位数应该是num[2]×10+num[3]num[2]×10+num[3]。

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 == c * target) {
          ++res;
        }
      }
    }
    // 调用函数生成全排列
  } while (next_permutation(num, num + 9));

你可以想象在num这9个数中间画两条线,这样就把这9个数分成三段了对吧,而且是一定要分成三段的,要保证每一段都至少有一个数。所以第一段最多只能选到第七个,如果第一段就选了八个数的话,只剩下一个数,这样就不够分了呀。第二段同理,如果第二段选到了第九个数,那第三段就没数可以选了。

举报

相关推荐

0 条评论