《算法笔记》第三章--入门模拟 例题

题目图片来源:《算法笔记》第三章

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;
	
} 

改进建议

  1. 对于没有必要保存到数组的数据可以直接操作。
  2. 在统计同一个编号的学校总分时,计算复杂,没有必要去遍历以后再加分。直接使用读取的编号重新放在数组里面. 即实际上只需要进行分类过后的编号和成绩,进行一个累加即可。这样做也节省了很多的空间。

修改代码

#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;
	
} 

改进建议

  1. 需要注意的细节是输入的数据为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;
}

改进建议

  1. 判断平闰年的函数模块可以再简写。
  2. 在读取的操作上并没有完全符合题目要求,以致于判断两者日期前后的逻辑变复杂。

修改代码

#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];
		}
    
}

改进注意

  1. 注意分割词语的时候,需要在每行后面加上一个’\0’,才能保证使用puts\printf输出是正确的。
  2. 代码还可以利用EOF进行简化,判断单词输出的结束。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值