链接 : 传送们
这个式子是斐波那契数列的一个,更多见 斐波那契数列常见式子
那这道题就简单了,就是x 是否为斐波那契数列
1. 是 输出 x! 在m进制下的末尾0的个数
2. 不是 输出 z (1-13) 皇后问题的个数
一 求末尾0的个数
10进制下如何求 ? 那就是求 2和5的个数 why? 2*5=10 正好为10 ,其他进制也一样,只需找到所有相乘为m的数的个数,但x太大,肯定没办法直接暴力求,于是想办法简化 , 任何数都能由质数
的乘积构成 而我们求的就是乘积等于m的数的个数 于是就变成了求质数的个数 ,把m分解为质数,然后求x!中有多少个
二 求n皇后问题
先上代码
int uplimit;
void dfs(int row,int ld,int rd){
if(row!=uplimit){
int pos=uplimit& (~(row|ld|rd)); //取反 求能放的位置
while(pos){ //循环求所有放的可能
int p=pos&-pos; // 等价于 pos&(~pos+1) 末尾1 从末尾一个一个尝试放
pos-=p;
dfs(p|row,((ld | p)<<1),(rd | p)>>1);
//p|row 放的位置为p p|row 就是放好的 (ld | p) << 1 左斜线 (rd | p) 右斜线线
}
}
else ans++;
}
uplimit 就是放完 也就是 (1 < < n ) -1 变成二进制是n个 1
ld 左边 rd 右边
初始化
uplimit =(1<<n)-1
dfs(0,0,0) 初始未放 所以都为 0
代码 :
#include <bits/stdc++.h>
using namespace std;
long long fib[100];
long long maxx=1;
long long prime[] = {0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
long long ans=0;
int uplimit;
void dfs(int row,int ld,int rd){
if(row!=uplimit){
int pos=uplimit& (~(row|ld|rd));
while(pos){
int p=pos&-pos; // 等价于 pos&(~pos+1)
pos-=p;
dfs(p|row,((ld | p)<<1),(rd | p)>>1);
}
}
else ans++;
}
int num[66];
int wei=0;
int ling[20];
int cnt[40];
void solve(long long x,long long m){
for(int i=1;i<=25;i++){
while(m%prime[i]==0){
cnt[i]++;
m/=prime[i];
}
}
long long ans=1e18;
long long temp;
for(int i=1;i<=25;i++){
if(cnt[i]){
long long k=0;
temp=x;
while(temp){
temp/=prime[i];
k+=temp;
}
ans=min(ans,k/cnt[i]);
// cout<<prime[i]<<" "<<x<<" "<<k<<endl;
}
}
cout<<ans<<endl;
}
void init(){
fib[0]=1;
fib[1]=1;
fib[2]=2;
maxx=3;
while(fib[maxx-1]<=1e18){
fib[maxx]=fib[maxx-1]+fib[maxx-2];
maxx++;
}
for(int i=1;i<=13;i++)
{
uplimit= (1<<i)-1;
ans=0;
dfs(0,0,0);
ling[i]=ans;
}
}
int main()
{
init();
long long a;
int m;
cin>>a>>m;
if(fib[lower_bound(fib,fib+maxx,a)-fib]==a){
solve(a,m);
}
else
{
int z=(a% min(13,m))+1;
cout<<ling[z] ;
}
return 0;
}