zoukankan      html  css  js  c++  java
  • 蓝桥杯练习系统历届试题 带分数 dfs

    问题描述

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

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

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

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

    输入格式

    从标准输入读入一个正整数N (N<1000*1000)

    输出格式

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

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

    样例输入1
    100
    样例输出1
    11
    样例输入2
    105
    样例输出2
    6
     
    首先是暴力,TLE ,33分,讲道理我还想不到好嘛。
     1 // 纯纯的暴力 挂了。
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <iostream>
     5 using namespace std;
     6 
     7 int vis[10], visall[10];
     8 
     9 bool check(int num) {
    10     while(num) {
    11         int temp = num % 10;
    12         if (vis[temp]) return false;
    13         if (temp == 0) return false;
    14         vis[temp]++;
    15         num /= 10;
    16     }
    17     return true;
    18 }
    19 
    20 bool checkAll() {
    21     for (int i=1; i<10; ++i) {
    22         if (vis[i] != 1) return false;
    23     }
    24     return true;
    25 }
    26 
    27 void copyNum(int a[], int b[]) {
    28     for (int i=1; i<10; ++i) {
    29         a[i] = b[i];
    30     }
    31 }
    32 
    33 int main() {
    34     int n;
    35     while(cin >> n) {
    36         memset(vis, 0, sizeof(vis));
    37         memset(visall, 0, sizeof(visall));
    38         int ans = 0;
    39 
    40         for (int l=1; l<n; ++l) {
    41             memset(vis, 0, sizeof(vis));
    42             if (!check(l)) continue;
    43             copyNum(visall, vis);
    44 
    45             for (int down=1; down<100000; ++down) {
    46                 int up = (n-l) * down;
    47                 if (down > up) continue;
    48                 if (up % down) continue;
    49                 copyNum(vis, visall);
    50                 if (!check(down) || !check(up)) {
    51                         continue;
    52                 }
    53                 if (checkAll())  {
    54                     //cout << l << " " << down << " " << up << endl;
    55                     ans++;
    56                 }
    57             }
    58         }
    59 
    60         cout << ans << endl;
    61     }
    62     return 0;
    63 }
    View Code

    然后是优化。依然感觉dfs好神奇的说。

     1 /*
     2  刚才暴力的优化吧。
     3  先遍历左边的数字,然后dfs搜分母对应的长度 和 数字。
     4  */
     5 
     6 #include <stdio.h>
     7 #include <string.h>
     8 #include <iostream>
     9 using namespace std;
    10 
    11 int lens, v, ans;
    12 int vis[10], visall[10];
    13 
    14 bool check(int num) {
    15     int k = 0;
    16     while(num) {
    17         int temp = num % 10;
    18         if (vis[temp]) return false;
    19         vis[temp]++;
    20         k++;
    21         num /= 10;
    22     }
    23     lens = 9-k; // 剩余可用数字的个数
    24     return true;
    25 }
    26 
    27 void copyVis() {
    28     for (int i=0; i<10; ++i) {
    29         visall[i] = vis[i];
    30     }
    31 }
    32 
    33 int judge(int up) { // fenmu
    34     int k = 0;
    35     copyVis();
    36     while(up) {
    37        int temp = up % 10;
    38        if (visall[temp]) return -1;
    39        visall[temp] = 1;
    40        k++;
    41        up /= 10;
    42     }
    43     return k;
    44 }
    45 
    46 void dfs(int len, int val) { // len fenzi
    47     if (len > lens/2) return;
    48     if (judge(v*val) == lens-len) ans++;
    49     for (int i=1; i<10; ++i) {
    50         if (vis[i]) continue;
    51         vis[i] = 1;
    52         dfs(len+1, val*10+i);
    53         vis[i] = 0;
    54     }
    55 }
    56 
    57 
    58 
    59 int main() {
    60     int n;
    61     while(cin >> n) {
    62         ans = 0;
    63         for (int l=1; l<n; ++l) {
    64             memset(vis, 0, sizeof(vis));
    65             vis[0] = 1;
    66             if (!check(l)) continue;
    67             v = n - l;
    68             dfs(0, 0); // len fenmu
    69         }
    70         cout << ans << endl;
    71     }
    72     return 0;
    73 }
    View Code

    然后还有一种思路就是,对九个数字实现全排列,然后从八个空里找两个放+ 和 /。讲道理,这样的话,时间复杂度是10^6*8*7 不知道能不能过.....

  • 相关阅读:
    matlab curve fitting tool
    simulink model configuration parameter
    MATLAB小知识
    电源噪声与纹波
    各种“地”—— 各种“GND”
    一个不错的充电方案论坛:
    pre -regulator 前端稳压器
    LT4020替代方案
    power delivery功率输出
    LTC4020锂电池充电模块开发记录
  • 原文地址:https://www.cnblogs.com/icode-girl/p/5251780.html
Copyright © 2011-2022 走看看