蓝桥杯练习016
排列序数
题目描述
如果用 a b c d 这 4 个字母组成一个串,有 4!=24 种,如果把它们排个序,每个串都对应一个序号:
abcd 0
abdc 1
acbd 2
acdb 3
adbc 4
adcb 5
bacd 6
badc 7
bcad 8
bcda 9
bdac 10
bdca 11
cabd 12
cadb 13
cbad 14
cbda 15
cdab 16
cdba 17
⋯
现在有不多于 10 个两两不同的小写字母,给出它们组成的串,你能求出该串在所有排列中的序号吗?
输入描述
输入一行,一个串。
输出描述
输出一行,一个整数,表示该串在其字母所有排列生成的串中的序号。注意:最小的序号是 0。
输入输出样例
示例
bdca
11
运行限制
- 最大运行时间:1s
- 最大运行内存: 256M
思路
C++ 的 next_permutation(),它能从小到大逐个返回全排列。
首先对输入的串 s 排序,然后用 next_permutation() 输出全排列,
当全排列与初始的串相等时结束。
代码
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int main()
{
string s;
int cnt=0;
cin>>s;
string str=s;
sort(s.begin(),s.end());
do{
if(str==s){
cout<<cnt<<endl;
break;
}
cnt++;
}while(next_permutation(s.begin(),s.end()));
return 0;
}
带分数
题目描述
100 可以表示为带分数的形式:100 = 3 + 69258 / 714
还可以表示为:100 = 82 + 3546 / 197
注意特征:带分数中,数字 1~9 分别出现且只出现一次(不包含 0 )。
类似这样的带分数,100 有 11 种表示法。
输入描述
从标准输入读入一个正整数 N (N<1000 x 1000)。
输出描述
程序输出该数字用数码 1~9 不重复不遗漏地组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!
输入输出样例
示例
100
11
运行限制
- 最大运行时间:3s
- 最大运行内存: 64M
代码
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int parse(const 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;
int ans=0;
cin>>N;
string s="123456789";
do{
const char* str=s.c_str();
for(int i=1;i<=7;i++){
int inta=parse(str,0,i);
if(inta>=N)break;
for(int j=1;j<=9-i-1;j++){
int intb=parse(str,i,j);
int intc=parse(str,i+j,9-i-j);
if(intb%intc==0&&inta+intb/intc==N)ans++;
}
}
}while(next_permutation(s.begin(),s.end()));
cout<<ans<<endl;
return 0;
}
另外一类
既然题目中说「数字 1∼9 分别出现且只出现一次」,那么就暴力排列吧:对所有1∼9的排列,验证有几个符合要求。9个数共有 9! =362880 种排列,不会超时。
#include<bits/stdc++.h>
using namespace std;
int num[9]={1,2,3,4,5,6,7,8,9};
int check(int L,int R){
int res=0;
for(int i=L;i<=R;i++)
res=res*10+num[i];
return res;
}
int main(){
int n;
cin>>n;
int cnt=0;
while(next_permutation(num,num+9)){
for(int i=0;i<7;i++){
for(int j=i+1;j<8;j++){
int a = check(0,i);
int b = check(i+1,j);
int c = check(j+1,8);
if(a*c+b == c*n)
cnt++;
}
}
}
cout<<cnt<<endl;
return 0;
}