带分数
强行全排列,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; }
看了大佬的代码之后,才知道怎么回事。
①求出全排列
②对于每个全排列,遍历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; }