题号 | 分值 | 类型 |
---|---|---|
1006 Sign In and Sign Out | 25 | 简单模拟 |
1008 Elevator | 20 | 简单模拟 |
1036 boys VS girls | 25 | 简单模拟 |
1011 World Cup Betting | 10 | 简单模拟 |
1042 Shuffling Machine | 20 | 简单模拟 |
1046 Shortest Distance | 20 | 简单模拟 |
1065 A+B and C | 20 | 简单模拟 |
目录
1006 Sign In And Sign Out
给出n个人的id、sign in时间、sign out时间,求最早进来的人和最早出去的人的ID。
将时间都转换为总秒数,最早和最迟的时间保存在min和max中,并同时保存当前最早和最迟的人的ID,最后输出。
#include<iostream>
#include<string>
using namespace std;
int main() {
int M,hh,mm,ss;
string in, out, s1, s2, s3;
int in_time, out_time, min, max;
min = 23 * 60 * 60 + 59 * 60 + 59;
max = 0;
cin >> M;
for (int i = 0; i < M; i++) {
cin >> s1 >> s2 >> s3;
//记录时分秒
hh = (s2[0] - '0') * 10 + (s2[1] - '0');
mm = (s2[3] - '0') * 10 + (s2[4] - '0');
ss = (s2[6] - '0') * 10 + (s2[7] - '0');
in_time = hh * 60 * 60 + mm * 60 + ss;
if (in_time < min) {
min = in_time;
in = s1;
}
hh = (s3[0] - '0') * 10 + (s3[1] - '0');
mm = (s3[3] - '0') * 10 + (s3[4] - '0');
ss = (s3[6] - '0') * 10 + (s3[7] - '0');
out_time = hh * 60 * 60 + mm * 60 + ss;
if (out_time > max) {
max = out_time;
out = s1;
}
}
cout << in << " " << out;
system("pause");
}
这题没有给记录的最大数,想着复健下动态数组
当时不会cstdio所以输入处理有点呆,后来看了下笔记scanf可以直接处理这样的输入。
scanf("%d:%d:%d %d:%d:%d", &h1, &m1, &s1, &h2, &m2, &s2);
1008 Elevator
电梯从0层开始向上,给出该电梯依次按顺序停的楼层数,并且已知上升需要6秒/层,下降需要4秒/层,停下来的话需要停5秒,问走完所有需要停的楼层后总共花了多少时间。
用动态数组存储一下停靠的楼层即可,然后循环该数组一层一层的爬。
#include<iostream>
#include<vector>
using namespace std;
int main() {
int N, time=0;
int now = 0;
cin >> N;
vector<int> stop(N);
for (int i = 0; i < N; i++) {
cin >> stop[i];
}
time += 5 * N;
for (int i = 0; i < N; i++) {
if (stop[i] - now > 0) time += 6 * (stop[i]-now);
else time += 4 * (now - stop[i]);
now = stop[i];
}
cout << time;
return 0;
}
这题非常简单,不悟了。
1036 boys VS girls
顺序给出N个同学的信息,输出女生的最高分的信息和男生最低分的信息,并输出他们的分数差。如果不存在女生或男生,对应处输出Absent,差值输出NA。
需要记录的是男女学生信息和分数,这三者都只需要记录最值就可以,所以只更新最值信息就ok。用两个单位的string数组存储学生信息,用f_max和m_min存储分数信息。如果没更新过,说明这个case不存在男生/女生,输出absent和NA。
#include<iostream>
#include<climits>
#include<string>
using namespace std;
int main() {
int N, f_max=INT_MIN, m_min=INT_MAX;
string ID[2], name[2];
cin >> N;
for (int i = 0; i < N; i++) {
char gender; int score;
string s1, s2;
cin >> s1 >> gender >> s2 >> score;
if (gender == 'F') {
if (score > f_max) {
f_max = score;
name[0] = s1;
ID[0] = s2;
}
}
else {
if (score < m_min) {
m_min = score;
name[1] = s1;
ID[1] = s2;
}
}
}
if (f_max != INT_MIN) {
cout << name[0] << " " << ID[0] << endl;
}
else cout << "Absent" << endl;
if (m_min != INT_MAX) {
cout << name[1] << " " << ID[1] << endl;
}
else cout << "Absent" << endl;
if (f_max != INT_MIN&&m_min != INT_MAX)
cout << f_max - m_min;
else cout << "NA";
return 0;
}
*第一眼看感觉和1006差不多,果然(就是更新最值的模拟)。10分钟AC
1011 World Cup Betting
给出三场比赛以及每场比赛的W、T、L的赔率,选取每一场比赛中赔率最大的三个数a b c,先输出三行各自选择的是W、T、L中的哪一个,然后根据计算公式 (a * b * c * 0.65 – 1) * 2 得出最大收益。
以三个数一组的形式读取,读取完一组后输出最大值代表的字母,然后同时ans累乘该最大值,最后根据公式输出结果。
一开始我是这么写的,虽然AC了但是觉得写的很乱,不是很满意。再看了看我重复三遍的部分可以用循环代替,双层循环内结果累乘即可,就不用开三个数组了。👇错误示范
//这个是错误示范
#include<iostream>
#include<iomanip>
using namespace std;
int main() {
float g1[3], g2[3], g3[3];
char out[3] = { 'W','T','L' };
cin >> g1[0] >> g1[1] >> g1[2];
cin >> g2[0] >> g2[1] >> g2[2];
cin >> g3[0] >> g3[1] >> g3[2];
int index1 = 0;
float max=0.0;
for (int i = 0; i < 3; i++) {
if (g1[i] > max) {
max = g1[i];
index1 = i;
}
}
cout << out[index1] << " ";
int index2 = 0;
max = 0.0;
for (int i = 0; i < 3; i++) {
if (g2[i] > max) {
max = g2[i];
index2 = i;
}
}
cout << out[index2] << " ";
int index3 = 0;
max = 0.0;
for (int i = 0; i < 3; i++) {
if (g3[i] > max) {
max = g3[i];
index3 = i;
}
}
cout << out[index3] << " ";
cout << fixed << setprecision(2) << (g1[index1] * g2[index2] * g3[index3] * 0.65-1)*2;
system("pause");
}
再贴个优解:
#include <cstdio>
using namespace std;
int main() {
char c[4] = {"WTL"};
double ans = 1.0;
for(int i = 0; i < 3; i++) {
double maxvalue = 0.0;
int maxchar = 0;
for(int j = 0; j < 3; j++) {
double temp;
scanf("%lf", &temp);
if(maxvalue <= temp) {
maxvalue = temp;
maxchar = j;
}
}
ans *= maxvalue;
printf("%c ", c[maxchar]);
}
printf("%.2f", (ans * 0.65 - 1) * 2);
return 0;
}
1042 Shuffling Machine
简单模拟。使用start和end数组保存每一次变换的开始顺序和结束顺序(以1~54的编号存储),最后根据编号与扑克牌字母数字的对应关系输出end数组。
#include<iostream>
#include<string>
using namespace std;
int main() {
int K;
string init_cards[54];
string shuffle_cards[54];
int order[54];
for (int i = 1; i <=13; i++) {
init_cards[i-1] = "S" +to_string(i);
init_cards[13 + i - 1] = "H" + to_string(i);
init_cards[26 + i - 1] = "C" + to_string(i);
init_cards[39 + i - 1] = "D" + to_string(i);
}
init_cards[52] = "J1";
init_cards[53] = "J2";
cin >> K;
for (int i = 0; i < 54; i++) {
cin >> order[i];
order[i]--;
}
for (int i = 0; i < K; i++) {
for (int j = 0; j < 54; j++) {
shuffle_cards[order[j]] = init_cards[j];
}
if (i != K - 1) {
for (int j = 0; j < 54; j++) {
init_cards[j] = shuffle_cards[j];
}
}
}
for (int i = 0; i < 54; i++) {
cout << shuffle_cards[i];
if (i != 53) cout << " ";
}
system("pause");
}
AC花了19分钟 因为看题目看了好久
1046 Shortest Distance
简单模拟。所有结点连起来会形成一个环形,dis[i]存储第1个结点到第i个结点的下一个结点的距离,sum保存整个路径一圈的总和值。求得结果就是dis[right – 1] – dis[left – 1]和 sum – dis[right – 1] – dis[left – 1]中较小的那一个。
这道题的难点在于:如果只是简单的记录各个点之间的距离,每次询问的时候进行计算的话,最后一个测试点会运行超时,于是就改成数组(下文D)中记录的是,从一号点到当前点的总距离,查询的时候直接将距离相减就是正向的两个点之间的距离,反向的距离用总的环的距离减去。
注意:可能left和right的顺序颠倒了,所以用biger和smaller来算。
#include<iostream>
#include<algorithm>
using namespace std;
int main() {
unsigned long int N,M;
unsigned long int D[100001] = { 0 };
unsigned long int distance[10001] = { 0 };
unsigned long int sum=0;
cin >> N;
for (int i = 1; i <= N; i++) {
unsigned long int temp=0;
cin >> temp;
sum += temp;
D[i] = sum;
}
cin >> M;
for (int j = 0; j < M; j++) {
unsigned long int start, end;
cin >> start >> end;
unsigned long int bigger, smaller, distance1=0,distance2=0;
bigger=max(start,end);
smaller=min(start,end);
distance2 = D[bigger - 1] - D[smaller - 1];
distance1 = sum - distance2;
if (distance2 < distance1) distance[j]=distance2;
else distance[j] = distance1;
}
for (int i = 0; i < M; i++) {
cout << distance[i];
if (i != M - 1) cout << endl;
}
system("pause");
}
这题也是可以用动态数组,但是第一次提交的时候发现内存也没问题,就偷懒了。