3.13PAT乙级题库

素数判定:

bool function(int n){
    if(n == 2 || n == 3)
        return true;
    else{
        for(int i = 2; i <= sqrt(n); i++)//查看从2到(根号n)是否有它的因数
            if(n % i == 0)
                {return false;
                }
        return true;
    }

}

c++输出带小数的语句:


cout<<fixed<<setprecision(5)<<a;

1002 写出这个数

输入一个大数字,各位数字的和用拼音输出。

#include <bits/stdc++.h>
#include <stack>
using namespace std;
int main()
{ //二维数组存储相应拼音
    char pin[10][10]={"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
    int n,sum=0;
    // 定义一个栈
    stack<int> s;
    //输入一个长数字
    while((n=getchar())!='\n'){
        //转化为int型数字,同时每一位上的数字的和
        sum+=n-'0';
    }
    //分散数
    for(int i=0;i<3;i++){
        //入栈,先进后出,先进个位,再进十位,最后进百位。
        s.push(sum%10);
        sum/=10;
    }
    //在百位为0时 出栈
    while(s.top()==0){
        s.pop();
    }
    //读数,输出栈顶元素
    cout<<pin[s.top()];
    //出栈
    s.pop();
    //非空时 进行循环
    while(!s.empty()){
        // 输出栈顶元素
        cout<<" "<<pin[s.top()];
        //继续出栈。
        s.pop();
}
    return 0;
}
另解
#include<cstdio>
//定义一个函数
void print1(int x){
    switch(x){
    case 1:
        printf("yi");
        break;
    case 2:
        printf("er");
        break;
    case 3:
        printf("san");
        break;
    case 4:
        printf("si");
        break;
    case 5:
        printf("wu");
        break;
    case 6:
        printf("liu");
        break;
    case 7:
        printf("qi");
        break;
    case 8:
        printf("ba");
        break;
    case 9:
        printf("jiu");
        break;
    case 0:
        printf("ling");
        break;
    }
}
//运用递归,让数字分开逆序输出。
void print2(int x){
    if(x){
        print2(x/10);
        if(x>9)
            printf(" ");
        print1(x%10);
    }
}
int main(){
//字符串数组,可以直接输入
    char a[101];
    scanf("%s",a);
    int i=0;
    long long ans=0;
//字符型转换为int型
    while(a[i]){
        ans+=a[i]-'0';
        i++;
    }
//进行输出
    print2(ans);
    return 0;
}

扩展

1.getchar()函数的用法:
getchar函数是字符输入函数,其功能是从键盘上获取一个输入字符。

读取方式:

从stdio(输入)流中读字符,相当于getc(stdin),它从标准输入(键盘)里读取下一个字符。,返回值为用户输入的ASCⅡ码,出错返回-1,用户输入的字符被存放在键盘缓冲区中.直到输入回车键才从缓冲区依次提取字符,当用户键入回车之后,getchar会从输入流中读取第一个字符,

注意:

1.getchar只能输入一个字符。如果你输入多个字符,它只接受第一个字符。

2.如果输入流缓冲区中没有数据,那么getchar就会处于等待状态,从而使程序窗口停留。这也是为什么getchar可以作为暂停函数的原因。

2.scanf
scanf()函数是格式输入函数,即按用户指定的格式从标准输入设备(键盘) 上把数据输入到指定地址的变量中。

读取方式:

一般格式为:scanf(格式控制,地址列表)  也就是scanf("%?",&?);   可以读取相对于类型的数值并且存储到制定变量,并且可以读取多个数值,如数字,字符,字符串等    

注意:

scanf()在读取数字时会跳过空格、制表符和换行符!

两者区别:
1.scanf返回成功赋值项个数,并将数值赋值到指定参数上,而getchar只读取一个字符并返回其ascii码,并且可以赋值也可以不赋值。

scanf("%d",&a);
getchar();
ch =  getchar();   //两者都正确

2.结束输入的方式不同

scanf遇到 回车(enter),空格,TAB 就会结束一次输入,空格不会接收

getchar函数只以回车Enter结束输入,接受空格符。

3.

scanf在一次输入结束后,不会舍弃最后的回车符(即回车符会残留在缓冲区中)

getchar回车作为结束的标志,所以在敲回车时'\n'也被存入缓存

3.gets()函数的用法
gets()以Enter结束输入,但可以接受空格,会舍弃最后的回车符!并且gets()可以读取多个字符,就像%c字符与getchar()对应

而%s字符串与gets()对称

需要用getchar()吃掉回车的几种情况:

1. 前面有scanf 后面也要用scanf()时,中间要用一个空的getchar()吃回车;

2.   前面有scanf,后面要用ch=getchar()接收字符时,中间要用一个空的getchar()吃回车;

3.   2个ch=getchar()中间需要一个空的getchar()吃回车。

char二维数组的用法

int main() {
    // 定义二维字符数组
    char arr[3][10] = { "hello", "world", "c" };
    // 输出二维字符数组
    for (int i = 0; i < 3; ++i) {
        printf("%s\n", arr[i]);
    }
    return 0;
}

输入单词时,相当于一个字符串数组,3 是单词个数,10应该是单词最大长度。

1003 

题目:
卡拉兹(Callatz)猜想已经在1001中给出了描述。在这个题目里,情况稍微有些复杂。

当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中遇到的每一个数。例如对 n=3 进行验证的时候,我们需要计算 3、5、8、4、2、1,则当我们对 n=5、8、4、2 进行验证的时候,就可以直接判定卡拉兹猜想的真伪,而不需要重复计算,因为这 4 个数已经在验证3的时候遇到过了,我们称 5、8、4、2 是被 3“覆盖”的数。我们称一个数列中的某个数 n 为“关键数”,如果 n 不能被数列中的其他数字所覆盖。

现在给定一系列待验证的数字,我们只需要验证其中的几个关键数,就可以不必再重复验证余下的数字。你的任务就是找出这些关键数字,并按从大到小的顺序输出它们。

输入格式:
每个测试输入包含 1 个测试用例,第 1 行给出一个正整数 K (<100),第 2 行给出 K 个互不相同的待验证的正整数 n (1<n≤100)的值,数字间用空格隔开。

输出格式:
每个测试用例的输出占一行,按从大到小的顺序输出关键数字。数字间用 1 个空格隔开,但一行中最后一个数字后没有空格。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/qq_34451909/article/details/104653678

#include<cstdio>
#include<algorithm>
using namespace std;
bool cmp(int a,int b){
    return a>b;
}
int main(){
    int k;
    scanf("%d",&k);
    int a[k]={0};
    
    int flag[100010]={0};
    for(int i=0;i<k;i++){
        scanf("%d",&a[i]);
    }
    for(int i=0;i<k;i++){
        //定义一个临时变量
        int p=a[i];
        while(p!=1){
            if(p%2==0)
                p/=2;
            else
                p=(p*3+1)/2;
            // 每次变换后的p存到标志数组里,赋值 为1,表示出现了一次
            flag[p]=1;
        }
    }
    int arr[k]={0};
    int num=0;
    for(int i=0;i<k;i++){
        //如果没有这个数字,把这个数字整合到一个新数组里,
        if(!flag[a[i]])
            arr[num++]=a[i];
    }
    //对齐排序
    sort(arr,arr+num,cmp);
    for(int i=0;i<num;i++){
        printf("%d",arr[i]);
        //输出的同时保证末尾没有空格
        if(i<num-1)
            printf(" ");
    }
    return 0;
}

全排列排序函数

next_permutation 是 C++ STL 提供的一个函数,用于求一个序列的下一个字典序排列。next_permutation 函数包含在头文件 <algorithm> 中。其使用方法如下:

#include <algorithm>
using namespace std;

int main() {
    int a[] = {1, 2, 3};
    do {
        // 处理当前排列
    } while (next_permutation(a, a + 3));
    return 0;
}

其中,next_permutation 接受两个迭代器作为参数,表示要操作的序列的起始位置和结束位置。它会更改这个序列,让它成为下一个字典序排列,并返回一个 bool 值,表示是否成功生成下一个排列。当序列已经是字典序最大的排列时,不再存在下一个排列,函数将返回 false。

next_permutation 的原理其实并不复杂。它实际上是一个标准的全排列算法,对于当前排列从右往左依次找到一个逆序对,该逆序对左边的数字保持不变,右边的数字按照递减排序,然后得到下一个排列。

手动实现 next_permutation 的方法如下:

bool next_permutation(int* a, int n) {
    int i = n - 2;
    while (i >= 0 && a[i] >= a[i + 1]) {
        i--;
    }
    if (i < 0) {
        return false;
    }
    int j = n - 1;
    while (j >= 0 && a[i] >= a[j]) {
        j--;
    }
    swap(a[i], a[j]);
    reverse(a + i + 1, a + n);
    return true;
}

该实现接受一个整数数组 a 和数组的长度 n 作为参数,并修改 a 数组,使其成为下一个字典序排列。如果已经是最大的排列,则返回 false。

1~8 的全排列

#include<iostream>
#include<stack>
#include<algorithm>
using namespace std;

int main()
{
	int a[] = { 1,2,3,4,5,6,7,8 };
	do {
		for (int i = 0; i < 8; i++) {
			cout << a[i] << " ";
		}
		cout << endl;
	} while (next_permutation(a, a + 8));

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值