poj1150排列最后地非零位-数学

排列最后地非零位有2,5,3,7,9地次方来决定,而且这几个数地次方最后一位都是周期出现。

在计算地过程中先找出1……n中有多少2和5地幂,比如找2,先找出偶然n/2个,然后/2,再找。找到2和5地幂,比大小处理。

末尾数字3,5,7地处理花了写时间,先用处理类似2,5地循环来写总是出错。手工花了数据,发现是个树,只好dfs了。比如1……30,我们先统计除里面末位3地个数,我们在前面不断地除2,除5,因此要统计这时候3地个数,但是进行多次过程中n/2/5和n/5/2就重复统计了,因此要减去。


参考代码

#include<iostream>
#include<stdio.h>
using namespace std;
int p2[5]= {6,2,4,8,6},p3[5]={1,3,9,7,1},p7[5]={1,7,9,3,1},p9[5]={1,9,1,9};

int di(int n,int a) {
	int ans=0;
	while(n)
		ans+=n/a,n/=a;
	return ans;
}
int di379(int n,int a){
	int ans=0;
	//算自己
	//算除2,算除5
	if(n<=2)return 0;
	if(n%10>=a)ans++;
	ans+=n/10;
	ans+=di379(n/2,a)+di379(n/5,a)-di379(n/10,a);
	return ans;
}

int work(int n,int m) {
	int a2,a5,a3,a7,a9,ans=1;
	a2=di(n,2)-di(n-m,2);
	a5=di(n,5)-di(n-m,5);
	if(a2>a5)a2-=a5,a2%=4,ans=p2[a2];
	    else if(a2==a5) ans=1;
	         else {ans=5;cout<<5<<endl;return 0; }
	a3=di379(n,3)-di379(n-m,3);
	a7=di379(n,7)-di379(n-m,7);
	a9=di379(n,9)-di379(n-m,9);
	a3%=4;a7%=4,a9%=2;
	ans=ans*p3[a3]*p7[a7]*p9[a9]%10;
	return ans; 

}
int main() {
	int n,m;
	while(scanf("%d%d",&n,&m)==2) {
		int t=work(n,m);
		printf("%d\n",t);
	}
}


猜你喜欢

转载自blog.csdn.net/lengxuenong/article/details/79532215