首页 > 代码库 > 蓝桥杯 带分数

蓝桥杯 带分数

    怎么说呢,今天无聊就刷了一下蓝桥杯的题目,毕竟也参加了两届,虽然每次运气都很差。。。坑的一比,
废话不多说,今天刚好看了一下往届的比赛题目,偶然发现一题感觉思路一看就有,但是无从下手的题目,
没错,就像你搜的这样子,这道题目的名字就是“带分数”。

 

下面将题目都搬了过来:
问题描述
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 

 

    刚刚开始做的时候,直接就是一股劲的爆搜,看了看时间复杂度,估计超时不超时是五五开,就是将1-9这
9个数字进行全排列, 这个时间的复杂度是10!,用到了stl的一个全排列函数,叫做next_permutation,
想要了解更多的各位大大或者是萌新可以自己去百度一下这个的用法就是了,毕竟我们这个博客的主题还
是要针对这题题目来写的。
    虽然这个想法很危险,很容易超时。。。。但是好歹写出来再说,经过半小时的编程,我就蛋疼了,连
样例都是过不了的,于是ctrl + a,然后删除,直接推倒重写,这次估计了一下复杂的有美酒先
将这个数字表示为v = a + b / c;所以a肯定比v小,那么最外层就可以确定了,然后将
a进行拆分,进行判断,之后就是将没用到的数字存放在一个数组里面,利用stl的全排列,然后将之
后的数字进行组合,由于b/c这个形式,感觉就是b要比c大,同时整除,这时候又是一重剪枝,大概
的时间复杂度没去算过,反正提交一发,1a之后表示就没有去算过

  

下面是具体的事实表明可以,以及附上ac代码:

  技术分享

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;

int main(){
    
    int v, ans = 0;
    bool vis[11];
    scanf("%d", &v);
    for(int a=1; a<v; a++){
        int m = a, f = 0;
        memset(vis, false, sizeof(vis));
        while(m){// 判断当前数字之中的1-9只出现了一次 
            if(vis[m%10] == true || m % 10 == 0){
                f = 1;
                break;
            }else{
                vis[m%10] = true;
                m /= 10;
            }
        }
        if(f == 0){
            int len = 0, num[10];
            for(int i=1; i<=9; i++)
                if(vis[i] != true)
                    num[len++] = i;    
            while(next_permutation(num, num + len)){// 对剩下的数字进行全排列 
                int mid = (len - 1) / 2, bg = 9 - len;
                int b = 0;
                for(int i=0; i<mid; i++)
                    b = b * 10 + num[i];
                for(int i=mid; i<len-1; i++){
                    b = b * 10 + num[i];
                    int c = 0;
                    for(int j=i+1; j<len; j++)
                        c = c * 10 + num[j];
                    if(b < c)    continue;
                    if(b % c == 0 && a + b / c == v){// 满足条件时候,计数器自加1 
                        ans++; 
//                        printf("%d %d  %d\n", a, b, c);    
                    }
                }
            }
        }
    }
    printf("%d\n", ans);
    return 0;
}

 

蓝桥杯 带分数