练习9(数论初步)

A - 整除的尾数


一个整数,只知道前几位,不知道末二位,被另一个整数除尽了,那么该数的末二位该是什么呢?
Input
输入数据有若干组,每组数据包含二个整数a,b(0<a<10000, 10<b<100),若遇到0 0则处理结束。
Output
对应每组数据,将满足条件的所有尾数在一行内输出,格式见样本输出。同组数据的输出,其每个尾数之间空一格,行末没有空格。
Sample Input
200 40
1992 95
0 0
Sample Output
00 40 80
15

	#include<iostream>

	using namespace std;
	void print(int i){
		if(i<10) cout<<0;
		cout<<i;
	}
	int main(){
		int a,b;
		while(cin>>a>>b){
			if(a==0&&b==0) break;
			bool tag=false;
			for(int i=0;i<100;i++){
				int t=a*100+i;
				if(t%b==0){
					if(!tag)
						tag=true;
					else 
						cout<<" ";
					print(i);
				}
			}
			cout<<endl;
		}
	}

 

B - Number Sequence

 
A number sequence is defined as follows: 

f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7. 

Given A, B, and n, you are to calculate the value of f(n). 
Input
The input consists of multiple test cases. Each test case contains 3 integers A, B and n on a single line (1 <= A, B <= 1000, 1 <= n <= 100,000,000). Three zeros signal the end of input and this test case is not to be processed. 
Output
For each test case, print the value of f(n) on a single line. 
Sample Input
1 1 3
1 2 10
0 0 0
Sample Output
2
5

明显周期数列
方法1:
推到周期
#include<iostream>

using namespace std;
/*
1 1 16
1 2 18
1 3 24
1 4 48
2 1 12
2 2 48
*/
int f[100];
 int main(){
	int a,b,n;
	while(cin>>a>>b>>n,a||b||n){
	//if(a==0&&b==0&&n==0) break;
//	cout<<"i "<<1<<" "<<f[1]<<endl;
//	cout<<"i "<<2<<" "<<f[2]<<endl;
	int i;
	f[1]=1;f[2]=1;
//	f[3]=(a*f[1]+b*f[2])%7;
	for(i=3;i<100;i++){
		f[i]=(a*f[i-1]+b*f[i-2])%7;
//		cout<<i<<" "<<f[i]<<endl;
		if(f[i]==1&&f[i-1]==1) {
			break;
		}
	}
	//cout<<time<<endl;
	f[0]=f[i-2];
	n=n%(i-2);
//	for(int j=0;j<time;j++)
//		cout<<f[j]<<endl;
	cout<<f[n]<<endl;
	}
	return 0;
}
方法2:
知道周期, 不推,用一个比较大的数(周期倍数)
#include<iostream>

using namespace std;
 
int f[1009];
 int main(){
	int a,b,n;
	while(cin>>a>>b>>n,a||b||n){
	//if(a==0&&b==0&&n==0) break;
	int i;
	f[1]=1;f[2]=1;
	for(i=3;i<=1008;i++){
		f[i]=(a*f[i-1]+b*f[i-2])%7;
	}
	cout<<f[(n-1)%1008+1]<<endl;
	}
	return 0;
}

方法3:
矩阵快速幂

C - Factorial

 
The most important part of a GSM network is so called Base Transceiver Station (BTS). These transceivers form the areas called cells (this term gave the name to the cellular phone) and every phone connects to the BTS with the strongest signal (in a little simplified view). Of course, BTSes need some attention and technicians need to check their function periodically. 
ACM technicians faced a very interesting problem recently. Given a set of BTSes to visit, they needed to find the shortest path to visit all of the given points and return back to the central company building. Programmers have spent several months studying this problem but with no results. They were unable to find the solution fast enough. After a long time, one of the programmers found this problem in a conference article. Unfortunately, he found that the problem is so called "Travelling Salesman Problem" and it is very hard to solve. If we have N BTSes to be visited, we can visit them in any order, giving us N! possibilities to examine. The function expressing that number is called factorial and can be computed as a product 1.2.3.4....N. The number is very high even for a relatively small N. 

The programmers understood they had no chance to solve the problem. But because they have already received the research grant from the government, they needed to continue with their studies and produce at least some results. So they started to study behaviour of the factorial function. 

For example, they defined the function Z. For any positive integer N, Z(N) is the number of zeros at the end of the decimal form of number N!. They noticed that this function never decreases. If we have two numbers N1<N2, then Z(N1) <= Z(N2). It is because we can never "lose" any trailing zero by multiplying by any positive number. We can only get new and new zeros. The function Z is very interesting, so we need a computer program that can determine its value efficiently. 
Input
There is a single positive integer T on the first line of input. It stands for the number of numbers to follow. Then there is T lines, each containing exactly one positive integer number N, 1 <= N <= 1000000000. 
Output
For every number N, output a single line containing the single non-negative integer Z(N). 
Sample Input
6
3
60
100
1024
23456
8735373
Sample Output
0
14
24
253
5861
2183837



思路:n! 后面产生0 ,只有2*5  2的个数明显大于5的个数,只需求出能分解出多少个5
计算5的个数的方法
#include<iostream>
#include<cstdio>
using namespace std;


int main(){
	int T;
	cin>>T;
	while(T--){
		int n;
		scanf("%d",&n);
		__int64 ans=0;
		while(n){
			n/=5;
			ans+=n;
		}
		printf("%I64d\n",ans);
	}
}

D - Least Common Multiple

 
The least common multiple (LCM) of a set of positive integers is the smallest positive integer which is divisible by all the numbers in the set. For example, the LCM of 5, 7 and 15 is 105. 

Input
Input will consist of multiple problem instances. The first line of the input will contain a single integer indicating the number of problem instances. Each instance will consist of a single line of the form m n1 n2 n3 ... nm where m is the number of integers in the set and n1 ... nm are the integers. All integers will be positive and lie within the range of a 32-bit integer. 
Output
For each problem instance, output a single line containing the corresponding LCM. All results will lie in the range of a 32-bit integer. 
Sample Input
2
3 5 7 15
6 4 10296 936 1287 792 1
Sample Output
105
10296
#include<iostream>

using namespace std;

int n,m;
int *arr;

int gcd(int a,int b){
	return b!=0?gcd(b,a%b):a;
}

int lcm(int a,int b){
	return a/gcd(a,b)*b;//防止溢出
}

int main(){
	while(cin>>n){
		while(n--){
			cin>>m;
			arr=new int[m];
			cin>>arr[0];
			int ans=arr[0];
			for(int i=1;i<m;i++){
				cin>>arr[i];
				ans=lcm(ans,arr[i]);
			}
			cout<<ans<<endl;
		}
	}
	return 0;
}


求解最小公倍数和最大公约数的方法。。。

H - Romantic
The Sky is Sprite. 
The Birds is Fly in the Sky. 
The Wind is Wonderful. 
Blew Throw the Trees 
Trees are Shaking, Leaves are Falling. 
Lovers Walk passing, and so are You. 
................................Write in English class by yifenfei 

 

Girls are clever and bright. In HDU every girl like math. Every girl like to solve math problem! 
Now tell you two nonnegative integer a and b. Find the nonnegative integer X and integer Y to satisfy X*a + Y*b = 1. If no such answer print "sorry" instead. 
Input
The input contains multiple test cases. 
Each case two nonnegative integer a,b (0<a, b<=2^31) 
Output
output nonnegative integer X and integer Y, if there are more answers than the X smaller one will be choosed. If no answer put "sorry" instead. 
Sample Input
77 51
10 44
34 79
Sample Output
2 -3
sorry
7 -3
拓展欧几里得算法解不定方程的方法
注意调解的过程
若x,y为a*x+b*y=d的一个解
则 a*(x+b)+b*(y-a)=d x=x+b,y=y-a的一个解
拓展欧几里得:
对于a'=b,b'=a%b 而言,我们求得 x, y使得 a'x+b'y=Gcd(a',b')
由于b'=a%b=a-a/b*b (注:这里的/是 程序设计语言中的 除法)
那么可以得到:
a'x+b'y=Gcd(a',b') ===>
bx+(a - a / b * b)y = Gcd(a', b') = Gcd(a, b) ===>
ay +b(x - a / b*y) = Gcd(a, b)
因此对于a和b而言,他们的相对应的p,q分别是 y和(x-a/b*y)
使用扩展欧几里德算法解决不定方程的办法
对于不定整数方程pa+qb=c,若 c mod Gcd(a, b)=0,则该方程存在整数解,否则不存在整数解。
有种较为不严谨的方法证明,不过至少弥补了一点空白,望某些数论大师补充修改:
由于我们知道,存在一组x与y使得a*x+b*y=gcd(a,b)。
将等式两边同时乘以 整数k,即a*x*k+b*y*k=gcd(a,b)*k。如果c mod gcd(a,b)=f,则0<=f<gcd(a,b)。
那么可以令c=gcd(a,b)*k+f。这样一来,就有a*x*k+b*y*k+f=c。
若f
   
0,由于f<gcd(a,b)<=a<=b(假设a<=b),所以不存在f=a*m(m为整数),也就不存在a*(x*k+m)+b*y*k=c。也就是说,不存在a*x+b*y=c的整数解x与y。
所以f=0,即只有当c mod gcd(a,b)=0时,a*x+b*y=c有正整数解。得证。

#include<iostream>
#include<cstdio>
//typedef __int64 ll;

using namespace std;


int gcd(int a,int b,int& x,int& y){
	if(b==0){
		x=1;
		y=0;
		return a;
	}
	int d=gcd(b,a%b,y,x);
	y-=a/b*x;
	return d;
}

int main(){
	ios_base::sync_with_stdio(false);
	int a,b;
	while(cin>>a>>b){
		int x,y;
		int d=gcd(a,b,x,y);
		if(d==1){
			while(x<0){
				x+=b;
				y-=a;
			}
			cout<<x<<" "<<y<<endl;


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值