关于数论:数论专题BTBY基础上机试题

3次阅读

共计 4860 个字符,预计需要花费 13 分钟才能阅读完成。

BT: 漂亮数

小明很喜爱 3 和 5 这两个数字,他将能被 3 或 5 整除的数叫做漂亮数。当初给你一个整数 N(1<=N<=100000),你能通知小明第 N 个漂亮数是多少吗?
提醒 本题须要打表优化
参考代码:
https://paste.ubuntu.com/p/th…
输出
输出蕴含多组测试数据。每组输出一个整数 N(1<=N<=100000)。
输入
对于每组输出,输入第 N 个漂亮数。
样例输出 Copy
1
2
3
4
样例输入 Copy
3
5
6
9

//#include<iostream>
//#include<algorithm>
//#include<string>
//#include<string.h>
//using namespace std;
//
//int main(){
//    int n = 0;
//    int a[100005];
//    int count = 1;
//    for(int i = 1;; i++){// 须要应用数组先把对应的丑陋数存下来而后前面间接拜访数组下标即可,要不查找时工夫会超限 
//        if(i % 3 == 0 || i % 5 == 0){//            a[count] = i;
//            count ++;
//        }
//        if(count > 100000){
//            break;
//        }
//    }
//    while(scanf("%d",&n) != EOF){//        printf("%d\n",a[n]);
//    }
//    return 0;
//} 

BU: 一个数学问题

给你两个整数 n 和 m,请你计算有多少个整数对(a,b)满足以下条件:
当 0 <a<b<n 时,(a^2+b^2+m)/(ab)是一个整数。
输出
输出蕴含多组测试数据。每组输出为两个整数 n 和 m(0<n<=100),当 n =m= 0 时,输出完结。
输入
对于每组输出,输入样例标号和满足要求的整数对的个数。
样例输出 Copy
10 1
20 3
30 4
0 0
样例输入 Copy
Case 1: 2
Case 2: 4
Case 3: 5

//#include<iostream>
//#include<algorithm>
//#include<string>
//#include<string.h>
//using namespace std;
//
//int main(){
//    int n = 0, m = 0,count = 1;
//    while(scanf("%d %d",&n,&m),m || n){
//        int s = 0;
//        for(int a = 1; a < n; a++){//            for(int b = a + 1; b < n; b++){//                if((a * a + b * b + m) % (a * b) == 0){
//                    s++;
//                }
//            }
//        }
//        printf("Case %d: %d\n",count,s);
//        count ++;
//    }
//    return 0;
//} 

BV: 找新敌人

新年快到了,天勤筹备搞一个团聚,曾经晓得现有会员 N 人,把会员从 1 到 N 编号,其中会长的号码是 N 号,但凡和会长是老朋友的,那么该会员的号码必定和 N 有大于 1 的公约数,否则都是新敌人,当初会长想晓得到底有几个新敌人?请你编程序帮会长计算出来。
输出
第一行是测试数据的组数 CN(Case number,1<CN<10000),接着有 CN 行正整数 N(1<n<32768),示意会员人数。
输入
对于每一个 N,输入一行新敌人的人数,这样共有 CN 行输入。
样例输出 Copy
2
25608
24027
样例输入 Copy
7680
16016

//#include<iostream>
//#include<algorithm>
//#include<string>
//#include<string.h>
//using namespace std;
//
//int main(){// 这种办法尽管能得出正确答案,然而工夫复杂度较大,前面用欧拉方程计算 
//    int cn = 0;
//    int a[32769];
//    scanf("%d",&cn);
//    while(cn--){
//        int n = 0,count = 0;
//        int i,j;
//        scanf("%d",&n);
//        for(i = 1; i < n; i++){//            for(j = 2; j < n; j++){//                if(i % j == 0 && n % j == 0){
//                    break;
//                }
//            }
//            if(j == n){
//                count ++;
//            }
//        }
//        printf("%d\n",count);
//    }
//    return 0;
//} 

上面用欧拉函数相干定理的办法来解决这道题

///*
// 欧拉 φ 函数:φ(n)是所有小于 n 的正整数里,和 n 互素的整数的个数。n 是一个正整数。// 欧拉证实了上面这个式子:// 如果 n 的规范素因子合成式是 p1^a1*p2^a2*……*pm^am,其中众 pj(j=1,2,……,m)都是素数,而且两两不等。// 则有   φ(n)=n(1-1/p1)(1-1/p2)……(1-1/pm)   
// 利用容斥原理能够证实它。//*/
//
//#include <iostream>
//#include <cmath>
//using namespace std;
//int euler(int x)
//{
//    // 就是欧拉公式
//    int i, res=x;
//    for (i = 2; i < (int)sqrt(x * 1.0) + 1; i++)
//        if(x%i==0)
//        {//            res = res / i * (i - 1);
//            while (x % i == 0) x /= i; // 保障 i 肯定是素数
//        }
//    if (x > 1) res = res / x * (x - 1);
//    return res;
//}
//int main(void)
//{
//    int n;
//    cin>>n;
//    while(n--)
//    {
//        int a;
//        cin>>a;
//        cout<<euler(a)<<endl;
//
//    }
//}

BW: sqrt log sin 函数

小明的老师给小明安排了这样一道作业题,一个序列合乎以下定义:


现问你这个序列的第 n 项是多少?

输出
输出蕴含多组测试数据。每组输出一个整数 n(0<=n<=1000000),当输出 - 1 时,输出完结。
输入
对于每组输出,输入第 n 项的值,后果请 mod 1000000。
样例输出 Copy
0
-1
样例输入 Copy
1

//#include<iostream>
//#include<algorithm>
//#include<string>
//#include<cmath> 
//using namespace std;
///*
// 在运行代码的时候,操作系统会调配不同的内存区域来运行代码
//
// 栈区:由操作系统主动调配开释,寄存函数的参数值,局部变量的值;不须要时零碎会主动革除
// 堆区:由 new 调配的内存块,也就是说在代码中 new 一个数组,内存由堆区调配;堆区不禁编译器管,由利用程序控制(相当于程序员管制。如果程序员没有开释掉,程序完结后,操作系统会主动回收
// 数据区:也称全局区或者动态区,寄存全局的货色,比方全局变量(大数组尽量定义在 main 函数外,即放在数据区)
// 代码区:寄存执行代码的中央,相似 if else,while,for 这种语句
//*/ 
//
//int a[1000005];// 超大数组不应定义在 main 函数内,因为 main 函数外部数组会被调配在栈内(栈比拟小),容易导致栈溢出 
//int main(){
//    int n = 0;
//    double x,y,z,i;
//    a[0] = 1;
//    for(i = 1; i <= 1000000; i++){//        x = i - sqrt(i);// 留神 i 须要定义为 double 类型,因为其参加的运算后果需赋值给 double 类型 x.y.z 
//        y = log(i);//log()log 是 e 为底的对数 (对应 ln),log10() 是 10 为底的对数 
//        z = i * sin(i) * sin(i);
//        a[(int)i] = (a[(int)x] + a[(int)y] + a[(int)z]) % 1000000;
//    }
//    while(scanf("%d",&n) != EOF,n != -1){//        printf("%d\n",a[n]);
//    }
//    return 0;
//} 

BX: 算步数

给你坐标轴上的两个点 A 和 B,请问从 A 走到 B 起码须要多少步?
咱们对走的每一步的步长作出如下限度:
第一步和最初一步的步长必须是 1,其余的任意一步的步长必须比前一步的步长小 1、大 1 或相等。
输出
输出蕴含多组测试数据。每组输出两个整数 A 和 B(0<=A<=B<2^31)。
输入
对于每组输出,输入从 A 走到 B 起码须要多少步。
样例输出 Copy
45 48
45 49
45 50
样例输入 Copy
3
3
4

//#include<iostream>
//#include<algorithm>
//#include<string>
//#include<string.h>
//using namespace std;
//// 要晓得公式 1 +2+。。+n+。。+2+1=n*n,找到平方小于等于差值的的数字 t
//int main(){
//    long a = 0,b = 0,c,n,t,bu = 2;//bu 代表要走的总步数 = 2,首尾必须各走一步 
//    while(scanf("%ld %ld",&a,&b) != EOF){
//        c = b - a;
//        if(c == 0){//            printf("0\n");
//            continue;
//        }
//        for(t = 0; t * t <= c; t++);// 此处只循环找到最小的 t,只有循环条件,没有循环体 
//        t = t - 1;// 找到平方小于等于差值的的数字 t,最初求余,不得零就总数加 1,还有 int 会超时,要改用 long int
//        bu = 2 * t - 1; // 计算目前步数 
//        n = (c - t * t) / t;// 先求商,看还能有几个最大步数 
//        bu += n;// 把计算失去残余的最大步数放在最大步数之后(如 1234567654321 中 7 之后),总步数减少 / n 步 
//        if((c - t * t) % t == 0){//            printf("%ld\n",bu);
//        }else{//            printf("%ld\n",bu + 1);// 最初求余,不得零代表还残余步数,则多加一小步走完,总步数 bu 加 1
//        }
//    }
//    return 0;
//} 

BY: 寻找最低数

给你一个正整数 A(1<=A<=100),输入 A 的最低数。
例如,给你 A =26,咱们能够将 A 化成二进制为 11010,则 A 的最低数是 10,输入 10 的十进制为 2。
再例如,给你 A =88,咱们能够将 A 化成二进制为 1011000,则 A 的最低数是 1000,输入为 8。
输出
输出蕴含多组测试样例。每行输出一个正整数 A(1<=A<=100)。当输出 0 时,输出完结。
输入
对于每一个输出,输入对应的最低数。
样例输出 Copy
26
88
0
样例输入 Copy
2
8

//#include<iostream>
//#include<algorithm>
//#include<string>
//#include<string.h>
//#include<cmath>
//#include<math.h>
//using namespace std;
//
//int main(){//    int t = 0,i,j,k,a[15];
//    while(scanf("%d",&t) != EOF){//        if( t == 0){
//            break;
//        } 
//        i = 0;
//        while(t){// 十进制转二进制,切记计算失去的 01..... 逆序排列才是失去的二进制 
//            a[i++] = t % 2;
//            t /= 2;
//        }
////        while(t != 0){// 二进制转十进制 
////            a = t % 10;
////            t /= 10;
////            b = a * pow(2,k++);
////        }
//        k = 0;
//        for(j = 0; j < i; j++){//            if(a[j] == 1){
//                break;
//            }else{
//                k++;// 统计 1 后面有多少个 0 
//            }
//        }
////        int test  = pow(2,k);// 此处需注意 printf()在传递参数的时候不会进行类型转换
////        cout << test;
//        printf("%d\n",(int)pow(2,k));// 而 pow()的返回值是一个 double 型的值,故需在后面加(int)////        printf("%d\n",test); 
//    }
//    return 0;
//} 

正文完
 0