题目图片来源:《算法笔记》第三章
3.1 简单模拟
【PAT B1001】 害死人不偿命的(3n+1)猜想
题目描述
我的代码
#include<iostream>
using namespace std;
int main() {
int a, num=0;
cin >> a;
while (a != 1) {
if (a % 2 == 0) {
a /= 2;
num++;
}
else {
a = (3*a + 1) / 2;
num++;
}
}
cout << num << endl;
system("pause");
}
改进建议
1.不管奇数还是偶数a的处理都算是一次操作,因此num++合并成一次,简化代码。
修改代码
//3n+1猜想
#include<iostream>
using namespace std;
int main() {
int a, num=0;
cin >> a;
while (a != 1) {
if (a % 2 == 0) a /= 2;
else a = (3*a + 1) / 2;
num++;
}
cout << num << endl;
system("pause");
}
【PAT B1032】挖掘机技术哪家强
题目描述
我的代码
#include<iostream>
using namespace std;
int main(){
int N;
int maxScore,maxNum;
cin>>N;
int sum[N+1]={0}; //初始化
int num[N+1],score[N+1];
for(int i = 1;i<=N;i++){
cin>>num[i]>>score[i];
for(int j=1;j<=N;j++){
if(num[i]==j)
sum[j]+=score[i];
}
}
for(int j = 1;j<=N;j++){
if(sum[j]>maxScore){
maxNum=j;
maxScore=sum[j];
}
}
cout<<maxNum<<" "<<maxScore<<endl;
}
改进建议
- 对于没有必要保存到数组的数据可以直接操作。
- 在统计同一个编号的学校总分时,计算复杂,没有必要去遍历以后再加分。直接使用读取的编号重新放在数组里面. 即实际上只需要进行分类过后的编号和成绩,进行一个累加即可。这样做也节省了很多的空间。
修改代码
#include<iostream>
using namespace std;
int main(){
int N;
int maxScore,maxNum;
cin>>N;
int sum[N+1]={0}; //初始化
int num,score;
for(int i = 1;i<=N;i++){
cin>>num>>score;
sum[num]+=score;
}
for(int j = 1;j<=N;j++){
if(sum[j]>maxScore){
maxNum=j;
maxScore=sum[j];
}
}
cout<<maxNum<<" "<<maxScore<<endl;
}
3.2 查找元素
【codeup 1934】找x
题目描述
我的代码
#include<iostream>
using namespace std;
int main(){
int N,x;
cin>>N;
int num[N];
bool flag = false;
for(int i=0;i<N;i++){
cin>>num[i];
}
cin>>x;
for(int i=0;i<N;i++){
if(num[i]==x){
cout<<i;
flag=true;
}
}
if(!flag)
cout<<"-1"<<endl;
}
改进建议
- 需要注意的细节是输入的数据为n个不相同的数据,所以当查找到符合要求的下标时,就应该退出循环。
修改代码
for(int i=0;i<N;i++){
if(num[i]==x){
cout<<i;
flag=true;
break; //添加退出循环的语句
}
}
运行结果
3.3 图形输出
【PAT B1036】跟奥巴马一起编程
题目描述
我的代码
#include<iostream>
#include<cmath>
using namespace std;
int main(){
int col;
char c;
cin>>col>>c;
int row=(int)round(col/2.0); //对列数的一半四舍五入取整
for(int i=0;i<row;i++){
for(int j=0;j<col;j++){
if(i==0 || i==row-1) //首尾两行
cout<<c;
else{
if(j==0 || j==col-1)
cout<<c;
else
cout<<" ";
}
}
cout<<endl;
}
}
运行结果
3.4 日期处理
【codeup 1928】日期差值
题目描述
我的代码
#include<iostream>
#include<cmath>
using namespace std;
swap(int &a,int &b){
int temp = a;
a=b;
b=temp;
}
bool judgeYear(int year){
if((year % 4 == 0 and year % 100 != 0) or (year % 400 == 0))
return true;
else
return false;
}
int main(){
int year1,month1,day1;
int year2,month2,day2;
int monthCal[2][13]={{0,31,28,31,30,31,30,31,31,30,31,30,31},{0,31,29,31,30,31,30,31,31,30,31,30,31}}; //平年 闰年
scanf("%d%d%d",&year1,&month1,&day1);
scanf("%d%d%d",&year2,&month2,&day2);
int sum;
//默认日期1早于日期2,否则交换
if(year1>year2){ //若日期1晚于日期2
swap(year1,year2);
swap(month1,month2);
swap(day1,day2);
}else if(year1 ==year2){
if(month1>month2){
swap(month1,month2);
swap(day1,day2);
}else if(month1==month2){
if(day1>day2)
swap(day1,day2);
}
}
while(year2-year1>1){
if(judgeYear(year1+1)==true){ //是闰年
sum+=366;
}else{
sum+=365;
}
year1++;
}
while(!(year1==year2 && month1==month2 && day1==day2)){
day1++;
sum++;
int m=(judgeYear(year1)==true)?1:0;
if(day1==monthCal[m][month1]+1){
month1++;
day1=1;
}
if(month1==13){
year1++;
}
}
cout<<sum+1;
}
改进建议
- 判断平闰年的函数模块可以再简写。
- 在读取的操作上并没有完全符合题目要求,以致于判断两者日期前后的逻辑变复杂。
修改代码
#include<iostream>
#include<cmath>
using namespace std;
swap(int &a,int &b){
int temp = a;
a=b;
b=temp;
}
bool judgeYear(int year){
return ((year % 4 == 0 and year % 100 != 0) or (year % 400 == 0));
}
int main(){
int year1,month1,day1;
int year2,month2,day2;
int t1,t2;
int monthCal[2][13]={{0,31,28,31,30,31,30,31,31,30,31,30,31},{0,31,29,31,30,31,30,31,31,30,31,30,31}}; //平年 闰年
scanf("%d",&t1);
scanf("%d",&t2);
int sum;
//默认日期1早于日期2,否则交换
if(t1>t2) //若日期1晚于日期2
swap(t1,t2);
//对时间的分割处理
year1=t1/10000,month1=(t1-year1*10000)/100,day1=t1-year1*10000-month1*100;
year2=t2/10000,month2=(t2-year2*10000)/100,day2=t2-year2*10000-month2*100;
while(year2-year1>1){
if(judgeYear(year1+1)==true){ //是闰年
sum+=366;
}else{
sum+=365;
}
year1++;
}
while(!(year1==year2 && month1==month2 && day1==day2)){
day1++;
sum++;
int m=(judgeYear(year1)==true)?1:0;
if(day1==monthCal[m][month1]+1){
month1++;
day1=1;
}
if(month1==13){
year1++;
}
}
cout<<sum+1;
}
运行结果
3.5 进制转换
【PAT B1022】 D进制的A+B
题目描述
我的代码
#include<iostream>
using namespace std;
#define maxn 80
int main(){
int A,B; //十进制数
int D; //需要转化的进制
cin>>A>>B>>D;
int sum=A+B;
int arr[maxn];
int num=0;
do{
arr[num++]=sum%D;
sum=sum/D;
}while(sum!=0);
for(int i=num-1;i>=0;i--){
cout<<arr[i];
}
}
修改建议
1.要注意输出时应该是num-1位,由于之前的操作中,循环在走完最后一个除法过程时,结果还会自增。对应当前的num位置实际上数组没有存储元素。所以应该从num-1~0进行倒序输出。
进制转化知识点
3.6 字符串处理
【codeup 5901】 回文串
题目描述
我的代码
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=256;
bool JudgeHuiwen(char str[]){
int len=strlen(str);
int middle=len/2;
int begin=0;
int last=len-1;
while(last>=begin){
if(str[begin]==str[last]){
begin++;
last--;
}else
return false;
}
return true;
}
int main(){
char str[maxn];
while(gets(str)!=NULL){
if(JudgeHuiwen(str))
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
}
运行结果
【PAT B1009】说反话
题目描述
我的代码
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=80;
int main(){
char ans[90][90]; //store spilited words
char str[maxn];
gets(str); //when input string is not empty
int m=strlen(str);
int r=0,h=0; //control row and col
for(int i = 0; i < m;i++){
if(str[i]!=' ')
ans[r][h++]=str[i];
else{
ans[r][h]='\0';
r++; //next row
h=0;
}
}
for(int i =r;i>=0;i--){
if(i>0)
cout<<ans[i]<<" ";
else
cout<<ans[i];
}
}
改进注意
- 注意分割词语的时候,需要在每行后面加上一个’\0’,才能保证使用puts\printf输出是正确的。
- 代码还可以利用EOF进行简化,判断单词输出的结束。