标题:带分数
100可以表示为带分数的形式:100=3+69258/714
还可以表示为:100=82+3546/197;
注意特征:带分数中,数字1-9分别且只出现一次(不包含0)
类似这样的带分数,100有11种表示法
题目要求:
从标准输入读入一个正整数N(N<1000*1000)
程序输出该数字用1-9不重复不遗漏的组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!
例如:
用户输入:
100
程序输出:
11
思路:
首先想到的一定是全排列,构建一个string=“123456789”,在不同的位置插入‘+’ 和‘/’
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
//因为用substr会超时 所以这里写一个parse
int parse(char*arr,int pos,int len){
int ans=0;
int t=1;
for(int i=pos+len-1;i>=pos;i--){
ans+=(arr[i]-'0')*t;
t*=10;
}
return ans;
}
int main()
{
int N;
cin>>N;
int ws=0;
int count=0;
string s="123456789";构建一个等待全排列的串
do{
for(int i=1;i<=7;i++){//+号前的串的长度
//string a=s.substr(0,i);用substr会超时
int inta=parse((char*)s.c_str(),0,i);//把0开始的i个数转成int型
if(inta>=N)break;
for(int j=1;j<=9-i-1;j++){//+ /两个符号之间的长度
//string b=s.substr(i,j);
//string c=s.substr(i+j);
int intb=parse((char*)s.c_str(),i,j);//把i开始的j个数转成int
int intc=parse((char*)s.c_str(),i+j,9-j-i);
if(intb%intc==0&&inta+intb/intc==N){
count++; //如果满足条件count++
}
}
}
}while(next_permutation(s.begin(),s.end()));
cout<<count;
return 0;
}
傻掉了 更新一种解法 next-permutation可以直接对int进行全排列 上面的代码画蛇添足了
这样写代码量小 而且效率更高(上段代码 刚开始substr截取字符串 还要atoi超时以后才改成这样子,晕)
#include<iostream>
#include<algorithm>
using namespace std;
int N;
int num=0;
int a[]={1,2,3,4,5,6,7,8,9};
int parse(int a[],int l,int r){
int sum=0;
while(l<=r){
sum=sum*10+a[l];
l++;
}
return sum;
}
int main(){
cin>>N;
do{
for(int i=0;i<7;i++){//加号前面的数
int inta=parse(a,0,i);
if(inta>=N)break;
for(int j=i+1;j<9-1;j++){//+和/中间的数
int b=parse(a,i+1,j);
int c=parse(a,j+1,8);
if(inta+b/c==N&&b%c==0)num++;
}
}
}while(next_permutation(a,a+9));
cout<<num;
return 0;
}