【PAT甲级】 1006 1008 1036 1011 1042 1046 1065 简单模拟类题目 PAT (Advanced Level) Practice

题号分值类型
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

1008 Elevator

1036 boys VS girls

1011 World Cup Betting

1042 Shuffling Machine

1046 Shortest Distance 


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");
}

这题也是可以用动态数组,但是第一次提交的时候发现内存也没问题,就偷懒了。 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值