2011-0025
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
题目大意是给定一个k进制的数s,以字符串(包含0-9,A-Z,a-z,0<...<9<A<...<Z<a<...<Z)形式表示,求s!(同样表达成k进制)的末尾0的个数。[[BR]]
解法: 对k分解质因数,设k=p1^a1^*p2^a2^...*pm^am^, 然后计算(s!)=p1^b1^*p2^b2^*...*pm^bm^*...[[BR]]
ans=min(b1/a1,...,bm/am)[[BR]]
{{{
#include<iostream>
#include<string>
#include<cassert>
#include<algorithm>
//#include<ctime>
#include<cstring>
#include<cmath>
using namespace std;
//0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
long long powk[63][64]; //2=<k<=62;
int map[128];
int factork[63][63][2];
int prime[18]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61};// num is 18
void init()
{
int k,i;
for(k=2;k<=62;k++)
{
powk[k][0]=1;
for(i=1;i<=63;i++)
{
powk[k][i]=powk[k][i-1]*k;
}
}
for(i=0;i<=9;i++)
{
map['0'+i]=i;
}
for(i=0;i<=25;i++)
{
map['A'+i]=10+i;
}
for(i=0;i<=25;i++)
{
map['a'+i]=36+i;
}
for(k=2;k<=62;k++)
{
int tem=k;
int index=1;
for(i=0;i<18;i++)
{
int order=0;
while(tem%prime[i]==0)
{
order++;
tem/=prime[i];
if(tem%prime[i]!=0)
{
factork[k][index][0]=prime[i];
factork[k][index][1]=order;
index++;
}
}
}
factork[k][0][0]=index-1;// the number of k's factorization.
}
}
int main()
{
//time_t _start=clock();
//freopen("input_new","r",stdin);
//freopen("output_new","w",stdout);
init();
char s[100];
int k;
while(scanf("%s %d",s,&k)!=EOF)
{
//printf("%s\n",s);
//cout<<sizeof(s)<<endl;
assert(k<=62&&k>=2);
long long s2dec=0;
for(int i=0;i<strlen(s);i++)
{
s2dec+=map[s[i]]*powk[k][strlen(s)-i-1];
}
assert(log(s2dec*1.0)/log(2.0)<63);
int order[10];
long long num_up=0,num_down=1;
for(int i=1;i<=factork[k][0][0];i++)
{
long long tem=s2dec;
long long ans=0;
while(tem)
{
tem/=factork[k][i][0];
ans+=tem;
}
order[i]=ans;
if(i==1)
{
num_up=ans;
num_down=factork[k][i][1];
}
else if(ans/factork[k][i][1]<num_up/num_down)
{
num_up=ans;
num_down=factork[k][i][1];
}
}
long long output=num_up/num_down;
printf("%lld\n",output);
}
//time_t _end=clock();
//cout<<_end-_start<<endl;
//fclose(stdin);
//fclose(stdout);
return 0;
}
}}}
by quietsmile
题目大意是给定一个k进制的数s,以字符串(包含0-9,A-Z,a-z,0<...<9
解法: 对k分解质因数,设k=p1a1*p2a2...*pmam, 然后计算(s!)=p1b1*p2b2*...*pmbm*...
ans=min(b1/a1,...,bm/am)
#include<iostream>
#include<string>
#include<cassert>
#include<algorithm>
//#include<ctime>
#include<cstring>
#include<cmath>
using namespace std;
//0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
long long powk[63][64]; //2=<k<=62;
int map[128];
int factork[63][63][2];
int prime[18]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61};// num is 18
void init()
{
int k,i;
for(k=2;k<=62;k++)
{
powk[k][0]=1;
for(i=1;i<=63;i++)
{
powk[k][i]=powk[k][i-1]*k;
}
}
for(i=0;i<=9;i++)
{
map['0'+i]=i;
}
for(i=0;i<=25;i++)
{
map['A'+i]=10+i;
}
for(i=0;i<=25;i++)
{
map['a'+i]=36+i;
}
for(k=2;k<=62;k++)
{
int tem=k;
int index=1;
for(i=0;i<18;i++)
{
int order=0;
while(tem%prime[i]==0)
{
order++;
tem/=prime[i];
if(tem%prime[i]!=0)
{
factork[k][index][0]=prime[i];
factork[k][index][1]=order;
index++;
}
}
}
factork[k][0][0]=index-1;// the number of k's factorization.
}
}
int main()
{
//time_t _start=clock();
//freopen("input_new","r",stdin);
//freopen("output_new","w",stdout);
init();
char s[100];
int k;
while(scanf("%s %d",s,&k)!=EOF)
{
//printf("%s\n",s);
//cout<<sizeof(s)<<endl;
assert(k<=62&&k>=2);
long long s2dec=0;
for(int i=0;i<strlen(s);i++)
{
s2dec+=map[s[i]]*powk[k][strlen(s)-i-1];
}
assert(log(s2dec*1.0)/log(2.0)<63);
int order[10];
long long num_up=0,num_down=1;
for(int i=1;i<=factork[k][0][0];i++)
{
long long tem=s2dec;
long long ans=0;
while(tem)
{
tem/=factork[k][i][0];
ans+=tem;
}
order[i]=ans;
if(i==1)
{
num_up=ans;
num_down=factork[k][i][1];
}
else if(ans/factork[k][i][1]<num_up/num_down)
{
num_up=ans;
num_down=factork[k][i][1];
}
}
long long output=num_up/num_down;
printf("%lld\n",output);
}
//time_t _end=clock();
//cout<<_end-_start<<endl;
//fclose(stdin);
//fclose(stdout);
return 0;
}
by quietsmile