杭电 2017 复试真题汇总(仅题目 + 样例)
1. 关羽过关斩三将 start:15:56
输入四个人的武力值(大于 0 小于 50),若超过界限需要重新输入。关羽的武力值 x,将士武力值为 y,满足(x−y)2+(x−y)+41若为素数则关羽获胜。若关羽三次获胜输出 WIN,若失败则输出失败的将领序号(第几关)。
cpp
#include<bits/stdc++.h>
using namespace std;
bool isnumber(int x)
{
int flag=0;
if (i==1) return false;
for(int i=2;i<=sqrt(x);i++)
{
if(x%i==0)
{
return false; //不是素数返回
}
}
return true;
}
int main()
{
int x;
cin>>x;
for(int i=1;i<=3;i++)
{
int y;
cin>>y;
int temp=(x-y)*2+(x-y)+41;
if(!isnumber(temp))
{
cout<<i;
return 0;
}
}
cout<<"win";
}
2. 员工考勤
输入 N 个员工,每个员工包含:ID 号,上班时间,下班时间。输出:第一行:最早去的员工的 ID 和上班时间第二行:最迟走的员工的 ID 和下班时间第三行:工作最久的员工的 ID 和工作时长
Sample Input:
100001,07:00:00 17:00:00
100002,08:00:00 18:00:00
100003,09:00:00 21:00:00
Sample Output:
100001 07:00:00
100003 21:00:00
100003 12:00:00
cpp
#include<bits/stdc++.h>
using namespace std;
typedef struct{
string ID;
string go;
string back;
} people;
// 你的时间转换函数,保留
int strtoTime(string s){
int hour = stoi(s.substr(0,2));
int minute = stoi(s.substr(3,2));
int second = stoi(s.substr(6,2));
return hour*3600 + minute*60 + second;
}
// 你的判断函数,保留
bool check_early(string A, string B) {
return strtoTime(A) > strtoTime(B);
}
// 辅助函数:把秒数转回 HH:MM:SS 用于输出第三行
string secondsToTime(int totalSeconds) {
int h = totalSeconds / 3600;
int m = (totalSeconds % 3600) / 60;
int s = totalSeconds % 60;
char buf[10];
snprintf(buf, sizeof(buf), "%02d:%02d:%02d", h, m, s);
return string(buf);
}
int main() {
int N;
if (!(cin >> N)) return 0;
// 【修改点 1】:使用动态数组,符合 C++ 标准
people* employ = new people[N];
for(int i = 0; i < N; i++) {
cin >> employ[i].ID >> employ[i].go >> employ[i].back;
}
// 【修改点 2】:所有基准初始化为第 0 个人,防止 N=1 时越界
int t1 = 0, t2 = 0, t3 = 0;
string early = employ[0].go;
string latest = employ[0].back; // 这里应该是 back 而不是 go
int last1 = (strtoTime(employ[0].back) - strtoTime(employ[0].go));
for(int i = 1; i < N; i++) {
if(check_early(early, employ[i].go)) {
early = employ[i].go;
t1 = i;
}
if(!check_early(latest, employ[i].back)) {
latest = employ[i].back;
t2 = i;
}
int temp = (strtoTime(employ[i].back) - strtoTime(employ[i].go));
if(last1 < temp) {
last1 = temp;
t3 = i;
}
}
// 【修改点 3】:输出加上逗号分隔,并格式化最长工作时间
cout << employ[t1].ID << "," << employ[t1].go << endl;
cout << employ[t2].ID << "," << employ[t2].back << endl;
cout << employ[t3].ID << "," << secondsToTime(last1) << endl;
// 释放动态分配的内存
delete[] employ;
return 0;
}
3. 模板最大切割数量
有一个 M×N 的材料和一个 s×t 的模板,从材料中切除模板,求最大能切出来的不重叠模板的数量。
Sample Input:3 4
a b c d
c d a b
a c c d
2 2
a b
c d
Sample Output:2
cpp
#include<bits/stdc++.h>
using namespace std;
char arr[1000][1000] = {0};
char brr[1000][1000] = {0};
int vis[1000][1000] = {0};
int main()
{
int M, N, count = 0;
if (!(cin >> M >> N)) return 0;
// 读取材料
for(int i = 1; i <= M; i++)
{
for(int j = 1; j <= N; j++)
{
cin >> arr[i][j];
}
}
int s, t;
cin >> s >> t;
// 读取模板
for(int i = 1; i <= s; i++)
{
for(int j = 1; j <= t; j++)
{
cin >> brr[i][j];
}
}
int flag = 1, u, v;
// 【修改点1】边界控制:防止越界跑到材料外面去
for(int i = 1; i <= M - s + 1; i++)
{
for(int j = 1; j <= N - t + 1; j++)
{
flag = 1; // 完美!你把状态重置写对地方了
for(u = 1; u <= s; u++)
{
for(v = 1; v <= t; v++)
{
// 【修改点2】把 b 改成了 brr,修复编译报错
if((arr[i+u-1][j+v-1] != brr[u][v]) || vis[u+i-1][v+j-1])
{
flag = 0;
break;
}
}
if(!flag) break;
}
if(flag)
{
count++;
for(u = 1; u <= s; u++)
{
for(v = 1; v <= t; v++)
{
vis[i+u-1][j+v-1] = 1; // 这里的赋值和坐标完全正确!
}
}
}
}
}
cout << count << endl;
return 0;
}