前言
大一大二天天吃喝睡觉,不喜写代码,导致编码能力薄弱,到了今时今日,无论是读研还是就业都逃不过上机考试这关,遂开始练习解题能力。
书籍:《计算机考研机试指南(王道第二版》
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;
}