王道机试指南 复试机试准备day1

最近在准备复试机试,笔试,面试,焦头烂额(哭)。但是写了很多简单题吧,逐渐找到了大一时被devc++支配的恐惧。这些简单题虽然说是简单,但是acm的输入输出有些时候挺烦的,写惯了核心代码模式,再来自己写输入输出,还是比较烦人的。写了很多题目,如果不去总结,回忆就将变得迟钝起来。我一直觉得c++的stl容器真的是万能,太好用了,如果搞懂各个容器的底层原理,再来使用,那将没有任何问题。
首先是万能头文件#include<bits/stdc++.h>,这么多天不知道写了多少遍了,但是真的用了才知道有多妙,不用去记那些常用的算法、容器属于哪个头文件,我全都要。当然,一般包含万能头的话编译时间会变长,但是运行时间一般没问题。卡运行时长的一般都是要你用其他的方法,在时间复杂度上就有问题了。话不多说,先记录今天写过的题目

1、abc(清华大学复试上机题)

描述
设a、b、c均是0到9之间的数字,abc、bcc是两个三位数,且有:abc+bcc=532。求满足条件的所有a、b、c的值。
输入描述:
题目没有任何输入。
输出描述:
请输出所有满足题目条件的a、b、c的值。 a、b、c之间用空格隔开。 每个输出占一行。

清华北大好像都挺喜欢没有输入输出,枚举一个方程解法的题目的。

#include <iostream>
using namespace std;

int main() {
    int a, b, c;
    for (a = 1; a <= 9; a++) {
        for (b = 1; b <= 9; b++) {
            for (c = 0; c <= 9; c++) {
                if ((a*100 + b*10 + c + b*100 + c*10 + c == 532)) {
                    cout<<a<<" "<<b<<" "<<c<<endl;
                }
            }
        }
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

2、反序数(清华大学复试上机题)

描述
设N是一个四位数,它的9倍恰好是其反序数(例如:1234的反序数是4321) 求N的值
输入描述: 程序无任何输入数据。
输出描述:
输出题目要求的四位数,如果结果有多组,则每组结果之间以回车隔开。

#include <iostream>
using namespace std;

int main() {
    int a,b,c,d;
    for (a = 1; a <= 9; a++) {
        for (b = 0; b <=9; b++) {
            for (c = 0; c <= 9; c++) {
                for (d = 0; d <= 9; d++) {
                    int z = a*1000 + b*100 + c*10 + d;
                    int r = d*1000 + c*100 + b*10 + a;
                    if (z*9 == r) {
                        cout<<z<<endl;
                    }
                }
            }
        }
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

3、对称平方数1(清华大学复试上机题)

描述
打印所有不超过256,其平方具有对称性质的数。如2,11就是这样的数,因为22=4,1111=121。
输入描述:
无任何输入数据
输出描述:
输出具有题目要求的性质的数。如果输出数据不止一组,各组数据之间以回车隔开。

这里记住string变到int是stoi()函数,int变为字符串的是to_string()函数。

#include <bits/stdc++.h>
using namespace std;
bool isD(int x) {
    string str = to_string(x);
    for (int i = 0, j = str.size()-1; i < j; i++, j--) {
        if (str[i] != str[j]) {
            return false;
        }
    }
    return true;

}
int main() {
    for (int i = 0; i <= 256; i++) {
        if (isD(i*i)) {
            cout<<i<<endl;
        }
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

4、与7无关的数(北京大学复试上机题)

描述
一个正整数,如果它能被7整除,或者它的十进制表示法中某个位数上的数字为7, 则称其为与7相关的数.现求所有小于等于n(n<100)的与7无关的正整数的平方和。
输入描述:
案例可能有多组。对于每个测试案例输入为一行,正整数n,(n<100)
输出描述:
对于每个测试案例输出一行,输出小于等于n的与7无关的正整数的平方和。
示例1
输入:
21
复制
输出:
2336

#include <iostream>
using namespace std;

bool isR7(int x) {
    if (x%7 == 0) 
        return true;
    while (x) {
        int q = x % 10;
        if (q == 7) {
            return true;
        }
        x /= 10;
    }
    return false;
}
int main() {
    int n;
    cin>>n;
    int res = 0;
    for (int i = 1; i <= n; i++) {
        if (!isR7(i)) {
            res += i*i;
        }
    }
    cout<<res;
    return 0;
}
// 64 位输出请用 printf("%lld")

5、叠筐

Problem Description
需要的时候,就把一个个大小差一圈的筐叠上去,使得从上往下看时,边筐花色交错。这个工作现在要让计算机来完成,得看你的了。

Input
输入是一个个的三元组,分别是,外筐尺寸n(n为满足0<n<80的奇整数),中心花色字符,外筐花色字符,后二者都为ASCII可见字符;

Output 输出叠在一起的筐图案,中心花色与外筐花色字符从内层起交错相叠,多筐相叠时,最外筐的角总是被打磨掉。叠筐与叠筐之间应有一行间隔。

Sample Input
11 B A 5 @ W

AAAAAAAAA
ABBBBBBBBBA
ABAAAAAAABA
ABABBBBBABA
ABABAAABABA
ABABABABABA
ABABAAABABA
ABABBBBBABA
ABAAAAAAABA
ABBBBBBBBBA
AAAAAAAAA

以下代码没经过oj测评,但是我运行检查了应该没问题

#include<bits/stdc++.h>
using namespace std;
int main () {
	int t;
	cin>>t;
	char w,n;
	cin>>w>>n;
	vector<vector<char>> matrix(t, vector<char>(t));
	for (int i = 0; i <= t/2; i++) {
		if (i % 2 == 0) {
//			上 下 
			for (int j = i; j < t-i; j++) {
				matrix[i][j] = w;
				matrix[t-i-1][j] = w; 
			}
//			左右 
			for (int j = i;j < t-i; j++) {
				matrix[j][t-i-1] = w;
				matrix[j][i] = w;
			}
		}
		else {
			//			上 下 
			for (int j = i; j < t-i; j++) {
				matrix[i][j] = n;
				matrix[t-i-1][j] = n; 
			}
//			左右 
			for (int j = i;j < t-i; j++) {
				matrix[j][t-i-1] = n;
				matrix[j][i] = n;
			}
		}	
	}
	for (int i = 0; i < t; i++) {
		for (int j = 0; j < t; j++) {
			if (i == 0 && j == 0 || i == t-1 && j == t-1|| i == 0 && j == t-1 || i == t-1 && j == 0) {
				cout<<" ";
			}
			else
				cout<<matrix[i][j];
		}
		cout<<endl;
	}
}				

6、今年的第几天?(清华大学复试上机题)

描述
输入年、月、日,计算该天是本年的第几天。
输入描述:
包括三个整数年(1<=Y<=3000)、月(1<=M<=12)、日(1<=D<=31)。
输出描述:
输入可能有多组测试数据,对于每一组测试数据, 输出一个整数,代表Input中的年、月、日对应本年的第几天。
示例1
输入:
1990 9 20
2000 5 1
复制
输出:
263
122

凡是遇到日期类问题,有闰年和非闰年的,直接vector数组列出来,注意全局vector和unordered_map都是先定义后面一个等号然后花括号,umap是{{key,value}};
判断是不是闰年采用如下方法:

 if (year % 400 == 0 || year % 100 != 0 && year % 4 == 0) 
 				是闰年,否则不是闰年
#include <bits/stdc++.h>
using namespace std;
vector<int> RunYearMonth = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
vector<int> GeneralYear = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int main() {
    int year, month, day;
    while (cin >> year >> month >> day) {
        // 闰年
        if (year % 400 == 0 || year % 100 != 0 && year % 4 == 0) {
            int res = 0;
            for (int i = 0; i < month - 1; i++) {
                res += RunYearMonth[i];
            }
            res += day;
            cout << res << endl;
        }
        // 普通年
        else {
            int res = 0;
            for (int i = 0; i < month-1; i++) {
                res += GeneralYear[i];
            }
            res += day;
            cout << res << endl;
        }
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

7、打印日期(华中科技大学复试上机题)

描述
给出年分m和一年中的第n天,算出第n天是几月几号。
输入描述:
输入包括两个整数y(1<=y<=3000),n(1<=n<=366)。
输出描述:
可能有多组测试数据,对于每组数据, 按 yyyy-mm-dd的格式将输入中对应的日期打印出来。
示例1
输入:
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

输出2001-03-01类型的数据用cout不好输出,记住采用
printf("%04d-%02d-%02d\n",04d表示有4位数据,靠右对齐,左边不足用零填充。顺便复习以下输出两位小数printf("%.2f",float)
cout输出两位小数为cout<<fixed<<precision(2)<<num<<endl;

#include <bits/stdc++.h>
using namespace std;
vector<int> RunYearMonth = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
vector<int> GeneralYear = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int main() {
    int year, days;
    while (cin >> year >> days) {
        // 闰年
        if (year % 400 == 0 || year % 100 != 0 && year % 4 == 0) {
            int res = days;
            int month;
            for (int i = 0; res >= RunYearMonth[i]; i++) {
                res -= RunYearMonth[i];
                month = i;
            }
            printf("%04d-%02d-%02d\n",year,month+2,res);
        }
        // 普通年
        else {
            int res = days;
            int month;
            for (int i = 0; res >= GeneralYear[i]; i++) {
                res -= GeneralYear[i];
                month = i;
            }
            printf("%04d-%02d-%02d\n",year,month+2,res);
        }
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

8、日期累加(北京理工大学复试上机题)

描述
设计一个程序能计算一个日期加上若干天后是什么日期。
输入描述:
输入第一行表示样例个数m,接下来m行每行四个整数分别表示年月日和累加的天数。
输出描述:
输出m行,每行按yyyy-mm-dd的个数输出。
示例1
输入:
1
2008 2 3 100
复制
输出:
2008-05-13

累加可能导致天数达到上限,则增加月,可能月数达到上限,增加年。外层还需要加一个循环。

#include <bits/stdc++.h>
using namespace std;
vector<int> RunYearMonth = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
vector<int> GeneralYear = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int main() {
    int t;
    cin >> t;
    while (t--) {
        int year, month, day, add;
        cin >> year >> month >> day >> add;
        add += day;
        // 闰年
        while (add > RunYearMonth[month - 1] || add > GeneralYear[month - 1]) {
            if (year % 400 == 0 || year % 100 != 0 && year % 4 == 0) {
                while (add > RunYearMonth[month - 1]) {
                    add -= RunYearMonth[month-1];
                    month++;
                    if (month > 12) {
                        month %= 12;
                        year++;
                        break;
                    }
                }
            } else {
                while (add > GeneralYear[month - 1]) {
                    add -= GeneralYear[month-1];
                    month++;
                    if (month > 12) {
                        month %= 12;
                        year++;
                        break;
                    }
                }
            }
        }
        printf("%04d-%02d-%02d\n", year, month, add);
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

9、日期差值(上海交通大学复试上机题)

描述
有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天
输入描述:
有多组数据,每组数据有两行,分别表示两个日期,形式为YYYYMMDD
输出描述:
每组数据输出一行,即日期差值
示例1
输入:
20110412
20110422
复制
输出:
11

两个日期之间差的天数,用较小一天模拟走,去找到较大的一天,用到的步骤数。可以天数加加,到月底了,月增加,天数从1开始,到年底了,年份增加,月数从1开始,注意每一年是闰年还是平年。

#include <bits/stdc++.h>
using namespace std;
vector<int> Run = {31,29,31,30,31,30,31,31,30,31,30,31};
vector<int> General = {31,28,31,30,31,30,31,31,30,31,30,31};
int main() {
    string a, b;
    while (cin >> a >> b) {
        // 小的在前,大的在后
        if (a > b) {
            swap(a, b);
        }
        int lyear = (a[0] - '0') * 1000 + (a[1] - '0') * 100 + (a[2] - '0') * 10 + a[3] - '0';
        int lmonth = (a[4] - '0') * 10 + a[5] - '0';
        int lday = (a[6] - '0') * 10 + a[7] - '0';
        int ryear = (b[0] - '0') * 1000 + (b[1] - '0') * 100 + (b[2] - '0') * 10 + b[3] - '0';
        int rmonth = (b[4] - '0') * 10 + b[5] - '0';
        int rday = (b[6] - '0') * 10 + b[7] - '0';
        int sum = 1;
        while ((lyear < ryear) || (lmonth < rmonth) || (lday < rday)) {
            lday++;
            // 闰年
            if ((lyear % 400 == 0) || (lyear % 100 != 0 && lyear % 4 == 0)) {
                if (lday == Run[lmonth-1]) {
                    lmonth++;
                    lday = 0;
                }
                if (lmonth == 13) {
                    lmonth %= 12;
                    lyear++;
                }
            }
            else {
                if (lday == General[lmonth-1]) {
                    lmonth++;
                    lday = 0;
                }
                if(lmonth == 13) {
                    lmonth %= 12;
                    lyear++;
                }
            }
            sum++;
        }
        cout<<sum<<endl;
    }
}
// 64 位输出请用 printf("%lld")

10、日期类(北京理工大学复试上机题)

描述
编写一个日期类,要求按xxxx-xx-xx 的格式输出日期,实现加一天的操作。
输入描述:
输入第一行表示测试用例的个数m,接下来m行每行有3个用空格隔开的整数,分别表示年月日。测试数据不会有闰年。
输出描述:
输出m行。按xxxx-xx-xx的格式输出,表示输入日期的后一天的日期。
示例1
输入:
2
1999 10 20
2001 1 31
复制
输出:
1999-10-21
2001-02-01
复制
备注:
注意个位数日期前面要有0。

有了前面题的铺垫,这题就很简单了。加一天,则考虑极端情况,day+1大于本月month了,那么

#include <bits/stdc++.h>
using namespace std;
vector<int> month = {0, 31,28,31,30,31,30,31,31,30,31,30,31};
int main() {
    int t;
    cin>>t;
    while (t--) {
        int y, m ,d;
        cin>>y>>m>>d;
        d++;
        if (d > month[m]) {
            m++;
            d = 1;
        }
        if (m > 12) {
            m = 1;
            y++;
        }
        printf("%04d-%02d-%02d\n",y,m,d);
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

11、剩下的树(清华大学复试上机题)

描述
有一个长度为整数L(1<=L<=10000)的马路,可以想象成数轴上长度为L的一个线段,起点是坐标原点,在每个整数坐标点有一棵树,即在0,1,2,…,L共L+1个位置上有L+1棵树。 现在要移走一些树,移走的树的区间用一对数字表示,如 100 200表示移走从100到200之间(包括端点)所有的树。 可能有M(1<=M<=100)个区间,区间之间可能有重叠。现在要求移走所有区间的树之后剩下的树的个数。
输入描述:
两个整数L(1<=L<=10000)和M(1<=M<=100)。 接下来有M组整数,每组有一对数字。
输出描述:
可能有多组输入数据,对于每组输入数据,输出一个数,表示移走所有区间的树之后剩下的树的个数。
示例1
输入:
500 3
100 200
150 300
470 471
复制
输出:
298

这题和代码随想录里合并区间那题很像,先按照左边界排序,相邻的区间合并,然后总数等于右区间减去左区间加一。没有做过还真不好写。

#include <bits/stdc++.h>
using namespace std;
bool cmp(const vector<int> &a, const vector<int> &b) {
    return a[0] < b[0];
}
int main() {
    int L;
    while (cin>>L) {
        int M;
        cin>>M;
        vector<vector<int>> nums(M, vector<int>(2));
        for (int i = 0; i < M; i++) {
            cin>>nums[i][0]>>nums[i][1];
        }
        // 按左边界对齐
        sort(nums.begin(), nums.end(), cmp);
        vector<vector<int>> data;
        data.push_back(nums[0]);
        for (int i = 1; i < nums.size(); i++) {
            if (nums[i][0] <= data.back()[1]) {
                // 右边界等于新加入和原来相比的最大值
                data.back()[1] = max(nums[i][1], data.back()[1]);         
            }
        }
        int reduce = 0;
        for (int i = 0; i < data.size(); i++) {
            reduce += data[i][1] - data[i][0]+1;
        }
        L = L+1-reduce;
        cout<<L<<endl;
    }
}
// 64 位输出请用 printf("%lld")

今天就先写这么多吧,明天再接再厉!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值