自然数

(数论)数的计算

旧街凉风 提交于 2020-04-03 07:13:00
题目描述 Description 我们要求找出具有下列性质数的个数(包含输入的自然数n): 先输入一个自然数n(n<=1000),然后对此自然数按照如下方法进行处理: 1. 不作任何处理; 2. 在它的左边加上一个自然数,但该自然数不能超过原数的一半; 3. 加上数后,继续按此规则进行处理,直到不能再加自然数为止. 输入描述 Input Description 一个数n 输出描述 Output Description 满足条件的数的个数 样例输入 Sample Input 6 样例输出 Sample Output 6 数据范围及提示 Data Size & Hint 6个数分别是: 6 16 26 126 36 136 分析: 1. 本题难度看似不大,但如果用递归来做的话耗时非常大,因为需要重复计算的数据量太大了。当然我们也可以采取一边递归一边储存的方法,但计算量也还是不小,再进一步思考,实际上就是可以用如下的递推法来做; 2. 例如要求f(6),经过分析,我们知道:f(6)=f(1)+f(2)+f(3)+1,也就是说,f(6)的答案数量是在它之前可以取的所有自然数的答案数量之和(6之前可以取1,2,3三个自然数),最后加1是指数字6本身也是一个答案; 3. 所以,我们可以知道f(n)=f(1)+f(2)+......f(trunc(n/2))+1; 4. 因此,要求f(n)

统计数字

吃可爱长大的小学妹 提交于 2020-03-29 12:54:51
【题目描述】 某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*10 9 )。已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果。 【输入格式】 包含n+1行: 第一行是整数n,表示自然数的个数; 第2~n+1每行一个自然数。 40%的数据满足:1<=n<=1000; 80%的数据满足:1<=n<=50000; 100%的数据满足:1<=n<=200000,每个数均不超过1500 000 000(1.5*10^9)。 【输出格式】 包含m行(m为n个自然数中不相同数的个数),按照自然数从小到大的顺序输出。每行输出两个整数,分别是自然数和该数出现的次数,其间用一个空格隔开。 【分析】 不能开桶,这个数据太大了,所以从小到大排序,然后从前向后枚举,找到全部相同的,直接输出就可以了。 【代码】 1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 int n; 6 int a[200010]; 7 8 int main() 9 { 10 scanf("%d",&n); 11 for(int i=1;i<=n;i++){ 12 scanf("%d",&a[i]); 13 } 14 sort(a+1,a+1+n); 15 int sum=1,now=a

统计数字

|▌冷眼眸甩不掉的悲伤 提交于 2020-03-26 04:01:19
#include <iostream> #include <cstdio> #include<cstring> #include<algorithm> using namespace std; int n; long long int a[200005]; int main() { while(cin>>n) { memset(a,0,sizeof(a));//对于每组输入清零 for(int i=1;i<=n;i++){ cin>>a[i]; } sort(a+1,a+n+1);//排序 a[n+1]=a[n]+1;//使最后一个不等于后一个 int sum=0; for(int i=1;i<=n;i++) { sum++; if(a[i]!=a[i+1]) {cout<<a[i]<<" "<<sum<<endl;//如果前后不相等说明当前数个数已统计完成 sum=0;//重新计算 } } cout<<endl; } //system("pause"); return 0; } 题目描述 某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*109)。已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果。 输入 每组输入数据包含n+1行; 第一行是整数n,表示自然数的个数; 第2~n+1行

质数——6N±1法

守給你的承諾、 提交于 2020-03-25 11:58:13
6N±1法求素数   任何一个自然数,总可以表示成为如下的形式之一:   6N,6N+1,6N+2,6N+3,6N+4,6N+5 (N=0,1,2,…)   显然,当N≥1时,6N,6N+2,6N+3,6N+4都不是素数,只有形如6N+1和6N+5的自然数有可能是素数。所以,除了2和3之外,所有的素数都可以表示成6N±1的形式(N为自然数)。   根据上述分析,我们只对形如6 N±1的自然数进行筛选,这样就可以大大减少筛选的次数,从而进一步提高程序的运行效率和速度。   以下代码需要自然数大于10 。   public int[] getPrimes(int n){   int []a = new int[200];   int k=0;   int num = 5;   a[0]=1;a[1]=2;a[2]=3;a[3]=5;a[4]=7;   for(int i=3;i< p>   for(int j=0;j<2;j++){   k = 2*(i+j)-1;   if((k<n)&&k%5==0?false:k%7==0?false:true){< p>   a[num] = k;   num++;   }   }   }   return a;   } 来源: https://www.cnblogs.com/fengshaolingyun/p/6785109.html

Python 入门练习实例五

筅森魡賤 提交于 2020-03-01 03:06:31
目录 Python 练习实例: Python 练习实例: 题目: 判断2-100之间有多少个素数,并输出所有素数。 程序分析: 质数(素数)是指在大于1的自然数中,除了1和它本身以外不再有其他 因数 的自然数 判断素数的方法:用一个数分别去除2到这个数,如果能被整除,则表明此数不是素数,反之是素数。 来源: CSDN 作者: Thinklov 链接: https://blog.csdn.net/u010244992/article/details/104579114

自然数的拆分

可紊 提交于 2020-02-04 19:15:19
任何一个大于1的自然数n,总可以拆分成若干个小于n的自然数之和。 当n=7共14种拆分方法: 7=1+1+1+1+1+1+1 7=1+1+1+1+1+2 7=1+1+1+1+3 7=1+1+1+2+2 7=1+1+1+4 7=1+1+2+3 7=1+1+5 7=1+2+2+2 7=1+2+4 7=1+3+3 7=1+6 7=2+2+3 7=2+5 7=3+4 total=14【输入】 输入n。 【输出】 按字典序输出具体的方案。 【输入样例】 7【输出样例】 7=1+1+1+1+1+1+1 7=1+1+1+1+1+2 7=1+1+1+1+3 7=1+1+1+2+2 7=1+1+1+4 7=1+1+2+3 7=1+1+5 7=1+2+2+2 7=1+2+4 7=1+3+3 7=1+6 7=2+2+3 7=2+5 7=3+4 思路 根据搜索回溯法,观察输出,发现最后一项1 变二且项数减少,即最后一次遍历时,使遍历停止的条件增加了1;要想按格式输出,还需要在输出时知道项数,因此,函数中应该有项数的变化和使遍历停止的条件的变化。 # include <iostream> using namespace std ; int n ; int a [ 100000 ] = { 1 } ; //输入的数的值的范围未给出,应该开大一些,但对于较大数据的测试,这种方法就有些不好了; void

PAT乙级1087(C++)——龙哥哥的刷题路

纵然是瞬间 提交于 2020-01-31 23:48:46
1087 有多少不同的值 (20分) 当自然数 n 依次取 1、2、3、……、N 时,算式 ⌊n/2⌋+⌊n/3⌋+⌊n/5⌋ 有多少个不同的值?(注:⌊x⌋ 为取整函数,表示不超过 x 的最大自然数,即 x 的整数部分。) 输入格式: 输入给出一个正整数 N(2≤N≤10^4)。 输出格式: 在一行中输出题面中算式取到的不同值的个数。 输入样例: 2017 输出样例: 1480 # include <iostream> # include <string> # include <cmath> # include <set> using namespace std ; int main ( ) { int N = 0 , sum = 0 , count = 0 ; set < int > nSet ; cin >> N ; for ( int i = 1 ; i <= N ; i ++ ) { sum = floor ( i / 2 ) + floor ( i / 3 ) + floor ( i / 5 ) ; if ( nSet . count ( sum ) == 0 ) { nSet . insert ( sum ) ; count ++ ; } } cout << count << endl ; return 0 ; } 来源: CSDN 作者: qq_23079139

luogu P1147 连续自然数和

北战南征 提交于 2020-01-27 03:03:19
题目描述 对一个给定的自然数M,求出所有的连续的自然数段,这些连续的自然数段中的全部数之和为M。 例子:1998+1999+2000+2001+2002 = 10000,所以从1998到2002的一个自然数段为M=10000的一个解。 输入输出格式 输入格式: 包含一个整数的单独一行给出M的值(10 <= M <= 2,000,000)。 输出格式: 每行两个自然数,给出一个满足条件的连续自然数段中的第一个数和最后一个数,两数之间用一个空格隔开,所有输出行的第一个按从小到大的升序排列,对于给定的输入数据,保证至少有一个解。 输入输出样例 输入样例#1: combo.in 10000 输出样例#1: combo.out 18 142 297 328 388 412 1998 2002 数学方法,推公式 自己看(当然不是我写的) #include<iostream> using namespace std; int main() { int i; double M,n; cin>>M; for(i=2000; i>=2; i--) { n=M/i; if(!(n-((int)n/1))) if(i%2) if((n-(i-1)/2)>0) cout<<(int)(n-(i-1)/2)<<" "<<(int)(n+(i-1)/2)<<endl; if((n-((int)n/1))==0

洛谷P1147 连续自然数和

青春壹個敷衍的年華 提交于 2020-01-25 00:25:22
题目解法: 这题是个大水题,但是我们看到了两种解法: 法一①:考虑前缀和做法。 首先我们读题,发现其要求的是连续自然数和。连续自然数和,那么我们可以用前缀和来处理这些自然数的和。于是我们得到了一个显然的做法:(30pts)直接枚举。 Code: #include<iostream> #include<cstdio> #define ll long long #define maxn 2000001 using namespace std; int m,s[maxn]; int main(){ cin>>m; s[0]=0; for(int i=1;i<=m;i++){ s[i]=s[i-1]+i; } for(int i=1;i<=m;i++){ for(int j=1;j<i;j++){ if(s[i]-s[j-1]==m){ cout<<j<<" "<<i<<endl; } } } return 0; } 法一②:考虑前缀和做法的优化版本。我们发现,在上一个阶段的代码上,我们可以对内层循环j做一些处理。比如,我们可以对这个j进行二分答案,得到一个j,然后从i到j,就是答案要求的区间。 Code: #include<iostream> #include<cstdio> #define maxn 2000001 #define int long long using

洛谷 P1147 连续自然数和

守給你的承諾、 提交于 2020-01-24 03:54:47
P1147 连续自然数和 思路: 设一段自然数的首项为 a 1 ,末项为 a 2 ,则这段自然数之和为: sum =(a 1 + a 2 ) * (a 2 - a 1 + 1) / 2 = m 即(a 1 + a 2 ) * (a 2 - a 1 + 1) = 2m 可以把2M分解成两个数之积,假设分成了两个数K1,K2,且K1<K2时, 可以列一个二元一次方程组: (1)a 2 - a 1 + 1 = K1 (2)a 1 + a 2 = K2 解得:a 1 = ( K2 - K1 + 1 ) / 2 , a 2 = ( K1 + K2 - 1 ) / 2 要保证a1和a2都为自然数,K2和K1必须是一个奇数,一个偶数 不过有一种特殊情况,就是a 1 = a 2 的情况,这种情况是不允许的 即(K2-K1+1)/2 ≠ (K1+K2-1)/2,解得K1≠1 代码如下: # include <iostream> # include <algorithm> # include <stdio.h> # include <cmath> typedef long long ll ; using namespace std ; int m , k1 , k2 ; int main ( ) { scanf ( "%d" , & m ) ; for ( k1 = sqrt ( 2 * m ) ;