带分数

强行全排列,9秒,11!的复杂度,稳妥超时:

代码:

#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <string.h>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map>

#define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 3000
#define MAX 0x06FFFFFF
#define V vector<int>

using namespace std;

int main(){
//    freopen("D:/CbWorkspace/blue_bridge/带分数.txt","r",stdin);
    int eq=100;
//    I("%d",&eq);
    string problem="+/123456789";
    do{
        int p=problem.find('+');
        int d=problem.find('/');
        if(abs(p-d)==1) continue;
        if(p==0 || d==0 || p==10 || d==10) continue;
        if(d<p) continue;
        int a,b,c;
        sscanf(problem.substr(p+1,d-p-1).c_str(),"%d",&b);
        sscanf(problem.substr(d+1,10-d).c_str(),"%d",&c);
        if(b%c) continue;
        sscanf(problem.substr(0,p).c_str(),"%d",&a);
        if((a+b/c)==eq) puts(problem.c_str());
    }while(next_permutation(problem.begin(),problem.end()));
    return 0;
}
View Code

 看了大佬的代码之后,才知道怎么回事。

①求出全排列

②对于每个全排列,遍历a最大能取到的位数(不会超过输入的num的位数),和c的最后一位(已知,就是list[8])得到b的最后一位。

③遍历到b的最后一位然后求出b和c,判断a、b、c是否满足条件。

AC代码:

#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <string.h>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map>

#define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 3000
#define MAX 0x06FFFFFF
#define V vector<int>

using namespace std;

int list[9];
int x;
int list2num(int a,int b){
    int i,ans=0;
    for(i=a;i<=b;i++){
        ans=ans*10+list[i];
    }
    return ans;
}
int getDigit(int n){
    int ans=0;
    do{
        ans++;
        n/=10;
    }while(n);
    return ans;
}

int main(){
//    freopen("D:/CbWorkspace/blue_bridge/带分数.txt","r",stdin);
    int i,j,a,b,c,num=100,cnt=0;
    I("%d",&num);
    FF(i,9) list[i]=i+1;//list初始化 
    x=getDigit(num) ;//获得输入num的位数,a是不会超过这个数的 
    do{
        for(i=0;i<x;i++){    //穷举 a 可能出现的位数 
            a=list2num(0,i);
            int bLastDigit=((num-a)*list[8])%10;    //b最后的数字
            for(j=((i+1)+8)/2;j<9 && list[j]!=bLastDigit ;j++);
            if(j>=8) continue;
            b=list2num(i+1,j);
            c=list2num(j+1,8);
//            cnt=0;
            if(b%c==0 && num==(a+b/c)) cnt++;
        }
    }while(next_permutation(list,list+9));
    O("%d",cnt);
    return 0;
}

 

posted @ 2018-03-25 21:23  TQCAI  阅读(359)  评论(0编辑  收藏  举报