PAT basic level

使用语言:C++
仅记录一下自己刷题过程的心得体会

永远保持更新(期待更好的解法)
可能有些题没有(那就是我还没做出来,以后会更的!)
欢迎大家与我讨论交流√

题目序列:

  • PAT basic level
    • 1001 害死人不偿命的(3n+1)猜想
    • 1002 写出这个数
    • 1003 我要通过!
    • 1004 成绩排名
    • 1006 换个格式输出整数
    • 1008 数组元素循环右移问题
    • 1071 小赌怡情
    • 1072 开学寄语
    • 1079 延迟的回文数

1001 害死人不偿命的(3n+1)猜想

题目:
卡拉兹(Callatz)猜想:
对任何一个正整数 n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把 (3n+1) 砍掉一半。这样一直反复砍下去,最后一定在某一步得到 n=1。卡拉兹在 1950 年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命想证明这个貌似很傻很天真的命题,结果闹得学生们无心学业,一心只证 (3n+1),以至于有人说这是一个阴谋,卡拉兹是在蓄意延缓美国数学界教学与科研的进展……

我们今天的题目不是证明卡拉兹猜想,而是对给定的任一不超过 1000 的正整数 n,简单地数一下,需要多少步(砍几下)才能得到 n=1?

** 输入格式:**
每个测试输入包含 1 个测试用例,即给出正整数 n 的值。

输出格式:
输出从 n 计算到 1 需要的步数。

输入样例:
3
输出样例:
5

解题思路:
很普通的一道题。就依照题目的要求,如果是偶数则除以2,是奇数则变为3n+1再除以2,中途用一个变量记录砍的次数,当n=1的时候停止循环并输出次数即可。

值得记下的点:

代码:

#include <stdio.h>
int main()
{int n,i,count=0; //count用于计数scanf("%d",&n);while(n!=1){if(n%2==0){n=n/2;count++;}else{n=(3*n+1)/2;count++;}}printf("%d",count);return 0;}

1002 写出这个数

题目:
读入一个正整数 n,计算其各位数字之和,用汉语拼音写出和的每一位数字。

输入格式:
每个测试输入包含 1 个测试用例,即给出自然数 n 的值。这里保证 n 小于 10100

输出格式:
在一行内输出 n 的各位数字之和的每一位,拼音数字间有 1 空格,但一行中最后一个拼音数字后没有空格。

输入样例:
1234567890987654321123456789
结尾无空行
输出样例:
yi san wu
结尾无空行

解题思路:
1.本题由于输入数字很大,所以输入类型选择字符串。
2.我的思路是将字符串的每一位都转换为数字,然后累加求和
3.求和后,将sum转换为字符串,然后再对应位置输出拼音(因为再变为字符串就不需要求余取位了,直接从字符串中0的位置开始对应输出即可)

值得记下的点:
利用C++中的strstream进行字符串和数字的类型转换

代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <strstream>
using namespace std;int main()
{string str;string num[] = {"ling", "yi", "er", "san", "si","wu","liu", "qi","ba", "jiu"};//这里只能用双引号int a=0;string sum;cin >> str;for(int i=0;i<str.length();i++){int temp;temp = str[i]-'0';a=a+temp;}strstream ss;ss << a;ss >> sum;int flag=0;for(int i=0;i<sum.length();i++){int temp;temp = sum[i]-'0';if(flag==0){cout << num[temp];flag=1;continue;}else{cout << " ";cout << num[temp];}    }return 0;
}

1003 我要通过!

题目:
“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。

得到“答案正确”的条件是:

字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;
任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
现在就请你为 PAT 写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。

输入格式:
每个测试输入包含 1 个测试用例。第 1 行给出一个正整数 n (<10),是需要检测的字符串个数。接下来每个字符串占一行,字符串长度不超过 100,且不包含空格。

输出格式:
每个字符串的检测结果占一行,如果该字符串可以获得“答案正确”,则输出 YES,否则输出 NO。

输入样例:
9
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA
APT
输出样例:
YES
YES
YES
YES
NO
NO
NO
NO
NO

解题思路:
这题很难!需要转化题目条件来进行判断。
分析条件:
1.字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;
翻译:P、T、A三种字符出现的次数相加一定要等于字符串的长度。因此想到设置cnt记下P、T、A的出现次数。

2.任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
翻译:说明P和T仅仅只可以出现一次。二者之间需要有一个A。

3.如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
翻译:P和T之间每增加一个A,字符串最后都需要增加一个A。可以得出P前面字符串长度乘以PT之间字符数目等于T后面字符的数目。

值得记下的点:
主要还是需要翻译题目条件,然后进行判断即可。

代码:

#include<iostream>
#include<stdio.h>
using namespace std;
int main()
{int n,i;scanf("%d",&n);while(n--){string str;cin>>str;int posP=0,posT=0;//记录P和T的位置int cntP=0,cntA=0,cntT=0;//记录PTA出现的次数for(i=0;i<str.length();i++){if(str[i]=='P'){posP=i;cntP++;}else if(str[i]=='A')cntA++;else if(str[i]=='T'){posT=i;cntT++;}}if(cntP+cntA+cntT<str.length()||cntP>1||cntT>1||posT-posP<=1||posP*(posT-posP-1)!=str.length()-posT-1)printf("NO\n");elseprintf("YES\n");}return 0;}

1004 成绩排名

题目:
读入 n(>0)名学生的姓名、学号、成绩,分别输出成绩最高和成绩最低学生的姓名和学号。

输入格式:
每个测试输入包含 1 个测试用例,格式为

第 1 行:正整数 n
第 2 行:第 1 个学生的姓名 学号 成绩
第 3 行:第 2 个学生的姓名 学号 成绩
… … …
第 n+1 行:第 n 个学生的姓名 学号 成绩
其中姓名和学号均为不超过 10 个字符的字符串,成绩为 0 到 100 之间的一个整数,这里保证在一组测试用例中没有两个学生的成绩是相同的。

输出格式:
对每个测试用例输出 2 行,第 1 行是成绩最高学生的姓名和学号,第 2 行是成绩最低学生的姓名和学号,字符串间有 1 空格。

输入样例:
3
Joe Math990112 89
Mike CS991301 100
Mary EE990830 95
输出样例:
Mike CS991301
Joe Math990112

解题思路:
很常规的一道题。创建一个结构体来储存学生的信息,在输入的时候就记下最大值和最小值的下标值,就不需要进行排序了。最后直接输出即可。

值得记下的点:
1.利用结构体
2.输入的同时直接作记录

代码:

#include<stdio.h>
#include<iostream>
using namespace std;
struct Node{string name;string code;int grade;
};
int main()
{int n;scanf("%d",&n);struct Node stu[n];int mmax,mmin,tarmax,tarmin;for(int i=0;i<n;i++){cin>>stu[i].name>>stu[i].code>>stu[i].grade;if(i==0){mmax=stu[i].grade;mmin=stu[i].grade;tarmax=tarmin=0;}else{if(mmax<stu[i].grade){mmax=stu[i].grade;tarmax=i;}if(mmin>stu[i].grade){mmin=stu[i].grade;tarmin=i;}}}   cout<<stu[tarmax].name<<" "<<stu[tarmax].code<<endl;cout<<stu[tarmin].name<<" "<<stu[tarmin].code<<endl;    return 0;
}

1006 换个格式输出整数

题目:
让我们用字母 B 来表示“百”、字母 S 表示“十”,用 12…n 来表示不为零的个位数字 n(<10),换个格式来输出任一个不超过 3 位的正整数。例如 234 应该被输出为 BBSSS1234,因为它有 2 个“百”、3 个“十”、以及个位的 4。

输入格式:
每个测试输入包含 1 个测试用例,给出正整数 n(<1000)。

输出格式:
每个测试用例的输出占一行,用规定的格式输出 n。

输入样例 1:
234
输出样例 1:
BBSSS1234
输入样例 2:
23
输出样例 2:
SS123

解题思路:
照题目说的做即可。
百位数上是n则输出n个B
十位数上是n则输出n个S
个位数上是n,则输出123…n(这以用个for循环来写)

值得记下的点:
取位数的方法

代码:

#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{int n,a,b,c,t=1,i;scanf("%d",&n);a=n%10;b=n/10%10;c=n/100;while(c!=0){printf("B");c--;}while(b!=0){printf("S");b--;}for(i=0;i<a;i++){printf("%d",t);t++;}return 0;}

1008 数组元素循环右移问题

题目:

输入格式:
每个输入包含一个测试用例,第1行输入N(1≤N≤100)和M(≥0);第2行输入N个整数,之间用空格分隔。

输出格式:
在一行中输出循环右移M位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。

输入样例:
6 2
1 2 3 4 5 6
输出样例:
5 6 1 2 3 4

解题思路:
题目要求是不允许使用另外的数组,一切比较和交换都在数组A中进行。
我想到的思路是把最后一位数储存起来,然后剩余数依次往后挪一位,再把第一位数设为最后一位数即可。
按以上方式循环M次即可完成右移。

代码:

#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{int i,j,temp,N,M,a[1000];scanf("%d%d",&N,&M);for(i=0;i<N;i++)scanf("%d",&a[i]);for(i=0;i<M;i++){temp=a[N-1];for(j=N-1;j>0;j--)a[j]=a[j-1];a[0]=temp;}for(i=0;i<N;i++){printf("%d",a[i]);if(i<N-1)printf(" ");}return 0;
}

1071 小赌怡情

题目:
常言道“小赌怡情”。这是一个很简单的小游戏:首先由计算机给出第一个整数;然后玩家下注赌第二个整数将会比第一个数大还是小;玩家下注 t 个筹码后,计算机给出第二个数。若玩家猜对了,则系统奖励玩家 t 个筹码;否则扣除玩家 t 个筹码。

注意:玩家下注的筹码数不能超过自己帐户上拥有的筹码数。当玩家输光了全部筹码后,游戏就结束。

输入格式:
输入在第一行给出 2 个正整数 T 和 K(≤ 100),分别是系统在初始状态下赠送给玩家的筹码数、以及需要处理的游戏次数。随后 K 行,每行对应一次游戏,顺序给出 4 个数字:

n1 b t n2

其中 n1 和 n2 是计算机先后给出的两个[0, 9]内的整数,保证两个数字不相等。b 为 0 表示玩家赌小,为 1 表示玩家赌大。t 表示玩家下注的筹码数,保证在整型范围内。

输出格式:
对每一次游戏,根据下列情况对应输出(其中 t 是玩家下注量,x 是玩家当前持有的筹码量):
玩家赢,输出 Win t! Total = x.;
玩家输,输出 Lose t. Total = x.;
玩家下注超过持有的筹码量,输出 Not enough tokens. Total = x.;
玩家输光后,输出 Game Over. 并结束程序。

输入样例 1:
100 4
8 0 100 2
3 1 50 1
5 1 200 6
7 0 200 8
输出样例 1:
Win 100! Total = 200.
Lose 50. Total = 150.
Not enough tokens. Total = 150.
Not enough tokens. Total = 150.

输入样例 2:
100 4
8 0 100 2
3 1 200 1
5 1 200 6
7 0 200 8
输出样例 2:
Win 100! Total = 200.
Lose 200. Total = 0.
Game Over.

解题思路:
1.本题比较简单,值得注意的是游戏结束时有两个条件,第一个条件是达到游戏次数,直接退出游戏,无任何提示;第二个条件是玩家的筹码数为0,此时有"Game Over."的提示
2.每次循环最后都要判断一下是不是输光了筹码

代码

#include<stdio.h>
#include<iostream>
using namespace std;
int T,k;
int main()
{scanf("%d %d",&T,&k);for(int i=0;i<k;i++){int n1,n2,b,t;scanf("%d %d %d %d",&n1,&b,&t,&n2);if(t>cnt){printf("Not enough tokens.  Total = %d.\n",cnt);continue;}if(n2>n1&&b==1||n2<n1&&b==0)//多个条件合并,简化代码{cnt+=t;printf("Win %d!  Total = %d.\n",t,T);}else{cnt-=t;printf("Lose %d.  Total = %d.\n",t,T);}if(T==0) //判断是否输光筹码{printf("Game Over.\n");break;}}return 0;}

1072 开学寄语

题目:
本题要求你写个程序帮助这所学校的老师检查所有学生的物品,以助其成大器。

输入格式:
输入第一行给出两个正整数 N(≤ 1000)和 M(≤ 6),分别是学生人数和需要被查缴的物品种类数。第二行给出 M 个需要被查缴的物品编号,其中编号为 4 位数字。随后 N 行,每行给出一位学生的姓名缩写(由 1-4 个大写英文字母组成)、个人物品数量 K(0 ≤ K ≤ 10)、以及 K 个物品的编号。

输出格式:
顺次检查每个学生携带的物品,如果有需要被查缴的物品存在,则按以下格式输出该生的信息和其需要被查缴的物品的信息(注意行末不得有多余空格):

姓名缩写: 物品编号1 物品编号2 ……
最后一行输出存在问题的学生的总人数和被查缴物品的总数。

输入样例:
4 2
2333 6666
CYLL 3 1234 2345 3456
U 4 9966 6666 8888 6666
GG 2 2333 7777
JJ 3 0012 6666 2333
输出样例:
U: 6666 6666
GG: 2333
JJ: 6666 2333
3 5

解题思路:
1.本来想的是设置一个数组来存放需被查的物体编号,但是发现利用桶更方便(因为不需要遍历,只要判断即可。),因此直接利用数组下标,如果需要被查则设置为1即可。
2.除此之外,本题正常输入和遍历即可,注意换行

#include <iostream>
#include <stdio.h>
using namespace std;
int N,M;
int ban[10005];//用于标记
int cnt1=0,cnt2=0;
int main()
{scanf("%d%d",&N,&M);for(int i=0;i<M;i++){int temp;scanf("%d",&temp);ban[temp]=1;}for(int i=0;i<N;i++){int flag=0;int K;string name;cin >> name >> K;int cnt=0;for(int j=0;j<K;j++){int num;scanf("%d",&num);if(ban[num]==1){cnt2++;//被查物体数加1if(flag==0){cout << name << ":";flag=1;//说明该学生带有被查物品}printf(" %04d",num);}}if(flag==1){cnt1++;printf("\n");//换行}}printf("%d %d\n",cnt1,cnt2);return 0;
}

1079 延迟的回文数

题目:

输入格式:
输入在一行中给出一个不超过1000位的正整数。

输出格式:
对给定的整数,一行一行输出其变出回文数的过程。每行格式如下

A + B = C
其中 A 是原始的数字,B 是 A 的逆转数,C 是它们的和。A 从输入的整数开始。重复操作直到 C 在 10 步以内变成回文数,这时在一行中输出 C is a palindromic number.;或者如果 10 步都没能得到回文数,最后就在一行中输出 Not found in 10 iterations.。

输入样例 1:
97152
输出样例 1
97152 + 25179 = 122331
122331 + 133221 = 255552
255552 is a palindromic number.

输入样例 2
196
输出样例 2:
196 + 691 = 887
887 + 788 = 1675
1675 + 5761 = 7436
7436 + 6347 = 13783
13783 + 38731 = 52514
52514 + 41525 = 94039
94039 + 93049 = 187088
187088 + 880781 = 1067869
1067869 + 9687601 = 10755470
10755470 + 07455701 = 18211171
Not found in 10 iterations.

解题思路:
这道题写了蛮久的,看似很简单但是有几蛮多点需要注意
1.这道题必须用字符串的相加,因为1000位数远远超过long long int可以储存的范围。因此需要写个函数实现字符串的相加

2.需要一个函数来判断字符串是否为回文数

3.写字符串相加函数时发现需要“将数字转换为字符串”,因此查了蛮多资料(比如itoa之类的),最后还是用stringstream来实现(因此又写了个将数字转换为字符串的函数。

4.将字符串逆序我用的是C++自带的reverse函数,使用方法是reverse(str.begin(),str.end()),该函数是直接改变str,没有返回值。

5.题目有个大坑点,就是可能这个数一开始就为回文数,那就不需要做任何逆序相加了,直接输出即可。

代码:

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <sstream>
using namespace std;
//函数:将数字转换为字符串
string numstr(int n)
{stringstream ss;ss << n;return ss.str();
}
//函数:判断该字符串是否为回文数
int is_huiwen(string str)
{string str0;str0 = str;reverse(str0.begin(),str0.end());if(str0==str)return 1;elsereturn 0;
}
//函数:让两个字符串相加
string plus_string(string str1,string str2)
{int length;length = str1.length();string str3;int k=0;int next;for(int i=length-1;i>=0;i--){if(i==length-1)next=0;int n1,n2;n1 = str1[i]-'0';n2 = str2[i]-'0';int n3=n1+n2+next;string temp;if(n3>9){n3=n3-10;next=1;temp=numstr(n3);str3+=temp;//本来想用的是str3[k++]=temp,但提示错误了,因此改成这个}else{next=0;temp=numstr(n3);str3+=temp;}}if(next==1){str3+='1';}reverse(str3.begin(),str3.end());return str3;
}
//主函数部分
int main()
{string str1,str2,str3;cin >> str1;int cnt=0;if(is_huiwen(str1)==1)cout << str1 << " is a palindromic number." << endl;else{while(cnt!=10){str2 = str1;reverse(str2.begin(),str2.end());//str1是逆转前的数 str2是逆转后的数cnt++;str3 = plus_string(str1,str2);cout << str1 << " + " << str2 << " = " << str3 << endl;if(is_huiwen(str3)==1){cout << str3 << " is a palindromic number." << endl;break;}elsestr1=str3;}if(cnt==10)printf("Not found in 10 iterations.\n");}return 0;
}

PAT basic level 答案+解题思路+难点 (个人刷题记录)相关推荐

  1. CTF MISC解题思路BUUCTF MISC1-8刷题

    1.签题--扫描二维码到得flag. 2.金*胖--题目为gif动画,用wps打开每帧保存成图片,flag就在其中几张图片. 3.二维码--下载题目解压得到一个二维码图片,扫描没发现flag.使用01 ...

  2. 1048 数字加密【PAT (Basic Level) Practice (中文)】

    1048 数字加密[PAT (Basic Level) Practice (中文)] 原题链接:1048 数字加密 (pintia.cn) 1.前言 PAT(乙级)2015年冬季考试 第三题 分数: ...

  3. PAT (Basic Level) Practice (中文)1058 选择题 (20 分)

    PAT (Basic Level) Practice (中文)1058 选择题 (20 分) 文章目录 PAT (Basic Level) Practice (中文)1058 选择题 (20 分) 题 ...

  4. 【题解】PAT (Basic Level) Practice (中文)

    互联网行业的小白,写博客的目的是为了记录自己的学习过程.对自己学习中所犯的错误做一个总结.由于水平有限,博客中难免会有一些错误出现,有纰漏之处恳请各位大佬不吝赐教! PAT Basic Level P ...

  5. PAT (Basic Level) Practice (中文)1070 结绳 (25 分) 凌宸1642

    PAT (Basic Level) Practice (中文)1070 结绳 (25 分) 凌宸1642 题目描述 给定一段一段的绳子,你需要把它们串成一条绳.每次串连的时候,是把两段绳子对折,再如下 ...

  6. 1001 害死人不偿命的(3n+1)猜想 (15分) PAT (Basic Level) Practice (中文)C语言版

    PAT (Basic Level) Practice (中文) 1001 害死人不偿命的(3n+1)猜想 (15分) 卡拉兹(Callatz)猜想: 对任何一个正整数 n,如果它是偶数,那么把它砍掉一 ...

  7. PAT (Basic Level) Practice (中文)1095 解码PAT准考证 (25 分)

    PAT (Basic Level) Practice (中文)1095 解码PAT准考证 (25 分) PAT 准考证号由 4 部分组成: 第 1 位是级别,即T代表顶级:A代表甲级:B代表乙级: 第 ...

  8. PAT (Basic Level) Practise (中文)-1025. 反转链表 (25)

    PAT (Basic Level) Practise (中文)-1025. 反转链表 (25)   http://www.patest.cn/contests/pat-b-practise/1025 ...

  9. PAT (Basic Level) Practise (中文)-1034. 有理数四则运算(20)

    PAT (Basic Level) Practise (中文)-1034. 有理数四则运算(20)  http://www.patest.cn/contests/pat-b-practise/1034 ...

最新文章

  1. 如何实现容器透明,内容不透明?
  2. Linux shell编程与实践(五)之shell程序中循环结构
  3. oracle 管道化表函数(Pipelined Table) [转]
  4. Python常用库及模块
  5. protobuf的安装和使用
  6. 协同过滤算法_机器学习 | 简介推荐场景中的协同过滤算法,以及SVD的使用
  7. 微型计算机各部件之间通过总线传递各种信息,2015年9月计算机一级考试基础及MSOffice应用选择真题...
  8. 单目视觉里程计 mono vo
  9. Go语言学习Day06
  10. 面试题13. 机器人的运动范围
  11. 十大热门的 JavaScript 框架和库
  12. H3C交换机创建用户
  13. Chrome 上最必不可少的29 款插件,超级提高效率
  14. Java泛型原理、类型擦除
  15. Linux下类似美图秀秀的软件,美图秀秀在Deepin下能用到Linux版、网页版及Wine版
  16. 10大优秀的移动Web应用程序开发框架
  17. pop3接收网易163邮件及下载超大附件
  18. python你实现视频自动打码,了解妨碍你观看精彩的马赛克是怎么精准形成的
  19. 使用HBuilder打包App教程
  20. OC中继承代理委托类别

热门文章

  1. 使用mpx开发外卖小程序完整教程(附源码)
  2. 富文本生成pdf-java
  3. Algorand正式开放测试网TestNet!
  4. 三维扫描系列 点云绪论
  5. 根据地址获取HTTP返回的状态码
  6. 计算机专业座谈会问题,我院计算机专业开展专业抽检主题座谈会
  7. linux ssh 终端退格键,退格键,Tab,Del和箭头键在终端中不起作用(使用ssh)
  8. 数据库系统概念 引言(一)
  9. 文件IO---标准输入、标准输出和标准错误
  10. select2回显操作