刷题笔记(一)《王道计算机考研机试指南2》

前言

大一大二天天吃喝睡觉,不喜写代码,导致编码能力薄弱,到了今时今日,无论是读研还是就业都逃不过上机考试这关,遂开始练习解题能力。

书籍:《计算机考研机试指南(王道第二版》

OJ平台:牛客网:考研复试专区

类型一:暴力计算

这类习题多为机试考试中的简单题和入门题。大多采用枚举等方法,由于数据量不大即使复杂度高也能完全跑出来。

奈何本人C语言基础实在过于将就,有些题目做起来依旧费劲。

1.反序数(THU)

输入一个数字,输出它的倒置数:
核心算法:每次循环取原数字的个位再将原数字除以10,revx保存倒置数,初始为0,每次循环*10再加上原数字的个位。

int Reverse(int x){
    int revx=0;
    while(x!=0){
        revx*=10;
        revx+=x%10;
        x/=10;
    }
    return revx;
}

2.佰鸡问题(HIT)

注意点:int相除除不尽会丧失精度,可通过数学变形避免分数

#include<iostream>

using namespace std;

int main(){
    int n;
    cin>>n;
    for(int x=0;x<=100;x++){
        for(int y=0;y<=100-x;y++){//必须注意,y的范围受制于x
           //if(5*x+3*y+(100-x-y)/3<=n){这里/3忽略了小数,所以错误,可以使用/3.0,自动转化double,提高精确度
           if(5*x*3+3*y*3+(100-x-y)<=n*3){//这样处理可以不用转化为double
            cout<<"x="<<x<<",y="<<y<<",z="<<100-x-y<<endl;
           }
        }
    }
    return 0;

}

3.与7无关(PKU)

4.火鸡 old bill(SJTU)

注意判断没有的情况,即判断价格到最后依旧=0

#include<iostream>
 using namespace std;
 int main(){
     int n;
     int sp=0;
     int x,y,z;
     int i,j;


     while(cin>>n>>x>>y>>z){//循环输入

     int xyz=100*x+10*y+z;
     for(int a=1;a<=9;a++){
        for(int b=0;b<=9;b++ ){
            if((a*10000+xyz*10+b)%n==0&&a*10000+xyz*10+b>=sp*n)
            {
                sp=(a*10000+xyz*10+b)/n;
                i=a;
                j=b;
            }
        }
     }

     if(sp==0)//判断没有正确情况
        cout<<0<<endl;
     else
        cout<<i<<" "<<j<<" "<<sp<<endl;

    }

     return 0;
 }

类型二:模拟输出

这类题目对我而言是个难关,这类题目没有高深的数学思想,能够比较纯粹的考察编码的细心和熟练。

1.叠筐

这个问题感觉还是比较奇特的

注意输出格式:每个之间空一行但最后一个没空行如何正确处理?

如何构造?规律是什么?

这道题确实花了很长时间,发现从内往外的规律,最里面第0层是字符A,往外交替,第偶数层A第奇数层B,填充四边的范围一定要精确,可以找个例子好好算一下范围。

#include<iostream>

using namespace std;

int main(){
    char matrix[80][80];
    int n;
    char a,c;
    bool firstK=true;

    while(scanf("%d %c %c",&n,&a,&c)!=EOF){

        if(firstK==true)//要求每个框之间有空行,最后一个框后面没有--》除了第一个框,其余所有框前面加一个空行
            firstK=false;
        else
            cout<<endl;

        //输出一个框,思路:输出n*n矩阵最后去掉四个角,发现一层一层交替产生
            //填充一圈,需要知道用哪个?难点,知道最中心的是a,每层往外就是ca交替
            //最中心就是0层,最外层就是n/2层
            //需要知道每圈的长度:第i层边长:2i+1

       //从内往外数,偶数层为a,奇数层为c;

        char tmp;
        for(int i=0;i<n/2+1;i++){
            if(i%2==0)
                tmp=a;
            else
                tmp=c;
            //填充四边
            for(int j=0;j<2*i+1;j++){
                matrix[n/2-i][n/2-i+j]=tmp;//上边
                matrix[n/2-i+j][n/2-i]=tmp;//左边
                matrix[n/2-i+j][n/2-i+2*i+1-1]=tmp;//右边
                matrix[n/2-i+2*i+1-1][n/2-i+j]=tmp;//下边
            }

        }

        if(n!=1){
            matrix[0][0]=' ';
            matrix[n-1][0]=' ';
            matrix[0][n-1]=' ';
            matrix[n-1][n-1]=' ';
        }

        for(int x=0;x<n;x++){
            for(int y=0;y<n;y++){
                cout<<matrix[x][y];
            }
            cout<<endl;
        }

    }
    return 0;

}

 

2.U型字符串(ZJU)

U型尽量的正:n1n2n3尽量等,可以用n+2/3,多出来的给n2

#include<iostream>

using namespace std;

int main(){
    string s;
    while(cin>>s){
        int n=s.size();
        int n1=(n+2)/3;
        int n2=n+2-2*n1;//要求n1,n2,n3,尽可能相等且n2>=n1,均分三分多出来的给n2即可
        //控制输出
        for(int i=0;i<n1-1;i++){
            cout<<s[i];
            for(int x=0;x<n2-2;x++)cout<<" ";//打印n2-2个空格
            cout<<s[n-1-i]<<endl;
        }
        for(int i=n1-1;i<n1+n2-1;i++){//注意范围
           // cout<<s[i]<<endl;错误
           cout<<s[i];
        }
        cout<<endl;

    }

}

类型三:日期类

1.打印日期(华科)

给出年年份m和一年中的第n天,算出第n天是几月几号。

输入包括两个整数y(1<=y<=3000),n(1<=n<=366)。

可能有多组测试数据,对于每组数据, 按 yyyy-mm-dd的格式将输入中对应的日期打印出来。

关键:判断闰年,格式输出

输入:

2000 3
2000 31
2000 40
2000 60
2000 61
2001 60

输出:

2000-01-03
2000-01-31
2000-02-09
2000-02-29
2000-03-01
2001-03-01
#include<iostream>

using namespace std;

int main(){
    int y,day;
    while((scanf("%d%d",&y,&day))!=EOF){
        int days[12]={31,28,31,30,31,30,31,31,30,31,30,31};
        int daysR[12]={31,29,31,30,31,30,31,31,30,31,30,31};
        bool isR=false;
        //判断闰年:4的倍数或400的倍数且不能是100的倍数
        if(y%4==0&&y%100!=0||y%400==0)
            isR=true;

        //求日期
        int i;
        int d=0;
        int dd=0;
        for( i=0;i<12;i++){
            if(isR)
                {
                    if(d+daysR[i]>=day){ dd=day-d;break;}
                    d+=daysR[i];
                }
            else
               {
                   if(d+days[i]>=day){dd=day-d;break;}
                   d+=days[i];//当时这里写反了检查了半天也没出来
               }
        }
        //cout<<y<<"-"<<i+1<<"-"<<dd<<endl;//不符合要求,题目要求输出格式2000-00-00
        //解决:
        printf("%4d-%02d-%02d",y,i+1,dd);

    }
}

2.日期累加(北理)

设计程序能计算一个日期加上指定天数后的日期

思路:不要钻牛角重复的判断今年闰明年后年啥情况。

正确思路是根据现有日期,求出今天是今年第几天,加上增加的天数,从而判断年份、月份、日期。

计算出today的天数+number=number,根据这个number判断年份是否增加(循环),根据这个number也可以推出日期。

#include<iostream>
#include <cstring>
using namespace std;

 int daysOfyear(int y){
        if(y%4==0&&y%100!=0||(y%400==0)){
            return 366;
        }else
        {return 365;}
    }
int isR(int y){
        bool isr=false;
        if(y%4==0&&y%100!=0||(y%400==0)){
            isr=true;
        }
        return isr;
    }

int main(){
    int daysIR[12]={31,28,31,30,31,30,31,31,30,31,30,31};
    int daysR[12]={31,29,31,30,31,30,31,31,30,31,30,31};
    int mday[12];
    int num;
    cin>>num;
    while(num--){
        int y,m,d,number;
        int y1,m1,d1;//目标年月日值
        cin>>y>>m>>d>>number;
        //判断闰年

        //总方向:确定年月日
        //不要把程序思路复杂化
        //先确定年份
        //确定今天是该年的第几天,加上需要增加的天数来判断年份,之后判断月份日子
        if(isR(y)){
            //mday=daysR;
            memcpy(mday,daysR,sizeof(daysR));//两个参数,一个目的一个源

        }else{
            //mday=daysIR;
           memcpy(mday,daysIR,sizeof(daysIR));
        }

        for(int i=0;i<m-1;i++)
            number+=mday[i];
        number+=d;
        //cout<<number<<endl;
        //确定年份
        while(number>daysOfyear(y)){
           number=number-daysOfyear(y);
           y++;
        }
        y1=y;

        //再判断一下年份是否闰年,选用合适的日数表
         if(isR(y1)){
            //mday=daysR;
            memcpy(mday,daysR,sizeof(daysR));//两个参数,一个目的一个源

        }else{
            //mday=daysIR;
           memcpy(mday,daysIR,sizeof(daysIR));
        }
        //确定月日;根据number确定月日
       for(m1=0;number>0;m1++){
            if(number-mday[m1]<=0)break;
            number-=mday[m1];
       }
       m1=m1+1;
       d1=number;

       printf("%04d-%02d-%02d\n",y1,m1,d1) ;

    }
    return 0;

}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值