作为一名参加过多次计算机机试的"老司机",我深知机试真题对备考的重要性。今天我将带大家详细拆解杭电计算机2016年的机试真题,从解题思路到代码实现,手把手教你如何应对这类考题。
题目要求:判断一个数N是否是素数,是的话输出"YES",否则输出"NO"。
素数判断是机试中的经典题型,看似简单实则暗藏玄机。我们先来看最直观的解法:
cpp复制bool isPrime(int n) {
if(n <= 1) return false;
for(int i=2; i<n; i++) {
if(n%i == 0) return false;
}
return true;
}
这个解法虽然正确,但效率太低。我们需要进行优化:
优化后的代码如下:
cpp复制#include <iostream>
#include <cmath>
using namespace std;
bool isPrime(int n) {
if(n <= 1) return false;
if(n == 2) return true;
if(n%2 == 0) return false;
for(int i=3; i<=sqrt(n); i+=2) {
if(n%i == 0) return false;
}
return true;
}
int main() {
int N;
while(cin >> N) {
if(isPrime(N)) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}
注意:在机试中,输入输出要严格按照题目要求,包括大小写和换行符。这道题的关键点在于理解素数的定义和掌握优化判断的方法。
题目要求:在二维平面内有n个点,求最近的两点距离。
这道题考察的是基础算法能力和暴力求解技巧。虽然更高效的算法如分治法可以达到O(nlogn)复杂度,但在机试中,数据规模通常不大,暴力解法完全可行。
解题步骤:
实现代码:
cpp复制#include <iostream>
#include <vector>
#include <cmath>
#include <climits>
using namespace std;
struct Point {
int x, y;
};
double calcDistance(const Point& a, const Point& b) {
return sqrt(pow(a.x-b.x, 2) + pow(a.y-b.y, 2));
}
int main() {
int N;
cin >> N;
vector<Point> points(N);
for(int i=0; i<N; i++) {
cin >> points[i].x >> points[i].y;
}
double minDist = INT_MAX;
for(int i=0; i<N; i++) {
for(int j=i+1; j<N; j++) {
double dist = calcDistance(points[i], points[j]);
if(dist < minDist) {
minDist = dist;
}
}
}
cout << minDist << endl;
return 0;
}
实际考试中,要注意浮点数精度问题。如果题目要求输出整数,可能需要四舍五入或取整处理。
题目要求:读取文件中的学生成绩,计算总分并排序,总分相同按学号升序。
这道题综合考查了文件操作、结构体使用和排序算法。虽然题目提到文件操作,但实际机试中可能简化输入方式。
解题要点:
实现代码:
cpp复制#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Student {
string id;
int num;
int chinese;
int math;
int english;
int total;
};
bool compare(const Student& a, const Student& b) {
if(a.total != b.total) {
return a.total > b.total;
}
return a.id < b.id;
}
int main() {
int N;
cin >> N;
vector<Student> students(N);
for(int i=0; i<N; i++) {
cin >> students[i].id >> students[i].num
>> students[i].chinese >> students[i].math >> students[i].english;
students[i].total = students[i].chinese + students[i].math + students[i].english;
}
sort(students.begin(), students.end(), compare);
for(const auto& s : students) {
cout << s.id << " " << s.num << " " << s.total << endl;
}
return 0;
}
如果题目要求文件操作,需要熟悉fstream的使用。另外,结构体排序是常考点,务必掌握自定义比较函数的写法。
题目要求:在大矩阵中寻找与小矩阵匹配度最高的位置(差值和最小)。
这道题难度较大,考察二维数组处理和暴力匹配能力。虽然暴力解法时间复杂度较高,但在限定条件下是可接受的。
解题思路:
实现代码:
cpp复制#include <iostream>
#include <vector>
#include <climits>
using namespace std;
int calculateDiff(const vector<vector<int>>& large, const vector<vector<int>>& small, int x, int y) {
int diff = 0;
for(int i=0; i<small.size(); i++) {
for(int j=0; j<small[0].size(); j++) {
diff += abs(large[x+i][y+j] - small[i][j]);
}
}
return diff;
}
int main() {
int N, M;
cin >> N >> M;
vector<vector<int>> large(N, vector<int>(M));
for(int i=0; i<N; i++) {
for(int j=0; j<M; j++) {
cin >> large[i][j];
}
}
int n, m;
cin >> n >> m;
vector<vector<int>> small(n, vector<int>(m));
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
cin >> small[i][j];
}
}
int minDiff = INT_MAX;
vector<pair<int, int>> positions;
for(int i=0; i<=N-n; i++) {
for(int j=0; j<=M-m; j++) {
int currentDiff = calculateDiff(large, small, i, j);
if(currentDiff < minDiff) {
minDiff = currentDiff;
positions.clear();
positions.emplace_back(i, j);
} else if(currentDiff == minDiff) {
positions.emplace_back(i, j);
}
}
}
cout << "最小距离为" << minDiff << ",对应的坐标起始点";
for(const auto& pos : positions) {
cout << "(" << pos.first << "," << pos.second << ")";
}
cout << endl;
return 0;
}
这类题目要注意边界条件的处理,确保不会越界访问数组。同时,输出格式要严格符合题目要求。
在准备机试过程中,我总结了一些常见问题和解决方法:
时间不够用:
边界条件考虑不周:
输出格式错误:
分类练习:
模拟考试环境:
错题复盘:
审题技巧:
调试技巧:
时间管理:
为了帮助大家更好地理解这些题目,我建议可以按照以下步骤进行练习:
例如,对于素数判断问题,可以尝试以下扩展:
对于最近点对问题,可以尝试:
通过这样的练习,你不仅能掌握基础解法,还能提升解决变种问题的能力。