欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

用老师讲的方法做的 题解

程序员文章站 2022-06-07 14:34:53
...

L2 - 032 彩虹瓶

题解
模拟堆箱子
现在纸上模拟一下 堆的过程 把样例模拟出来
发现 NO 的情况是 假如:想要3 3已经在堆的箱子里了
如果3正好是最上面的一个箱子的话 就直接拿出来
如果是3不是最上面的,3的上面还有一个5 这样的话基本就废了
就这样一直堆 直到到最大容量

贴一个老师的原版代码 ps: 加了个vector

#include <iostream>
#include <stack>
#include <vector>
using namespace std;
int N, M, K;
int check()
{
    //该放的瓶子数
    int cur = 1;
    // stack<int> s;
    vector<int> s;
    vector<int> v(N);
    for (int i = 0; i < N; ++i)
    {
        cin >> v[i];
    }
    for (int i = 0; cur <= N;)
    {
        //先看货架上有没有
        if (s.size() > 0 && s.back() == cur)
        // if (s.size() > 0 && s.top() == cur)
        {
            s.erase(s.end() - 1);
            // s.pop();
            ++cur;
        }
        else
        {
            //如果正好是那个该放的
            if (cur == v[i])
            {
                ++cur;
                ++i;
            }
            else
            {
                //加到货架里
                if (s.size() < M)
                    // s.push(v[i++]);
                    s.push_back(v[i++]);
                //货架放不下
                else
                    return 0;
            }
        }
    }
    return 1;
}
int main()
{
    cin >> N >> M >> K;
    while (K--)
    {
        cout << (check() ? "YES\n" : "NO\n");
    }
    return 0;
}

L1 - 049 天梯赛座位分配

题解
单独拿出一个数组把每个队伍的数量记住 方便后面处理
用一个vector二维数组 来记录 座位号
注释详细
#include <iostream>
#include <vector>
using namespace std;
int main()
{
	//用二位vector来存座号
	vector<vector<int>> tream(100);
	//存每个队伍的数量
	vector<int> num(100);
	int N;
	cin >> N;
	for (int i = 0; i < N; i++)
	{
		cin >> num[i];
	}
	//座号计数
	int cnt = 1;
	while (1)
	{
		//做一个退出的标记
		bool flag = false;
		for (int i = 0; i < N; i++)
		{
			//看看是不是已经安排完了
			if (num[i] * 10 > tream[i].size())
			{
				flag = true;
				//注意这个 
				//如果有的队伍人数很多 那个时候已经没有别的队伍了
				//即他的上一个是100 那么下一个该安排102
				//但是已经没有别的队伍了,所以就cnt就多加
				if (!tream[i].empty() && tream[i].back() == cnt - 1)
					cnt++;
				//一般情况
				tream[i].push_back(cnt++);
			}
		}
		if (flag == false)
			break;
	}
	for (int i = 0; i < N; i++)
	{
		cout << "#" << i + 1 << endl;
		for (int j = 0; j < num[i] * 10; j++)
		{
			cout << tream[i][j];
			//注意一下最后的情况
			if ((j + 1) % 10 == 0)
				cout << endl;
			else
				cout << ' ';
		}
	}
	return 0;
}

L2-027 名人堂与代金券

题解
用到了pair
就把他当成一个有两个元素的结构体即可
第一个元素是first 第二个是second
代金卷在输入的时候判断即可
主要是最后的那个排名
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
	vector<pair<string, int>> stu;
	int N, M, K;
	cin >> N >> M >> K;
	int sum = 0;
	for (int i = 0; i < N; i++)
	{
		string s;
		double a;
		cin >> s >> a;
		stu.push_back({s, a});
		if (a >= M && a <= 100)
			sum += 50;
		else if (a >= 60 && a < M)
			sum += 20;
	}
	sort(stu.begin(), stu.end(), [](auto e1, auto e2) { if(e1.second == e2.second)return e1.first < e2.first ;return e1.second > e2.second; });
	int cnt;
	cout << sum << endl;
	//用来做标记
	int t[104] = {0};
	for (int i = 0;i<stu.size(); i++)
	{
		//如果这个成绩曾经没出现过 就更新
		if (t[stu[i].second] == 0)
			cnt = i;
		t[stu[i].second] = 1;
		if (cnt > K)
			break;
		cout << cnt + 1 << ' ' << stu[i].first << ' ' << stu[i].second << endl;
	}
	return 0;
}

L1-043 阅览室

题解
用map来记录写代码很方便
map就是一个放东西的盒子 只是它是有两个放的地方 就像鸳鸯锅
特别的是map可以通过其中一个东西 找到另一个东西
map<键,值> 就当键是下标就行 通过键直接拿出值
在这个题里 用序号来当作键 再定义一个结构体来作为值
时间的话 可以一开始都变成分钟的样子 遇到E 直接减就行
就是这个 : time = 小时*60 + 分钟;

map的基本用法

#include <iostream>
#include <vector>
#include <map>
using namespace std;
struct node
{
    char c;
    int time;
};
int main()
{
    int N;
    cin >> N;
    while (N--)
    {
        int sum = 0;
        int cnt = 0;
        //序号做键 操作和时间作为值
        map<int, node> mp;
        while (1)
        {
            int a, c, d;
            char b;
            scanf("%d %c%d:%d", &a, &b, &c, &d);
            //一天的结束
            if (a == 0)
                break;
            //计算时间
            c = c * 60 + d;
            //mp.count(键) 查看map里有几个键为a的
            //其实 只返回0和1 因为map没有重复的
            //可以当作查看有没有这个键值来用
            if (mp.count(a) == 1 && mp[a].c == 'S' && b == 'E')
            {
                cnt++;
                sum += c - mp[a].time;
                //记得要删除 不然测试点1过不去 比如这个数据
                //1
                //1 S 9:50
                // 2 S 08:35
                // 1 E 10:00
                // 1 E 10:10
                // 0 S 17:00
                mp.erase(a);
            }
            else
                mp[a] = {b, c};
        }
        //                                  四舍五入
        cnt == 0 ? printf("0 0\n") : printf("%d %.0f\n", cnt, 1.0 * sum / cnt);
    }
    return 0;
}


L2-015 互评成绩

题解
用了老师说的两个函数
还有一个这样的函数 比较有意思
cout << fixed << setprecision(3) << 1.0 * ans[i] / (M-2);

用老师讲的方法做的 题解

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <iomanip>
using namespace std;
int main()
{
    int N, M, K;
    cin >> N >> M >> K;
    vector<int> ans;
    while (N--)
    {
        vector<int> v;
        int x;
        for (int i = 0; i < M; i++)
        {
            cin >> x;
            v.push_back(x);
        }
        //分别求他们最值的 迭代器 
        //用auto 很方便 删除的时候,参数也是迭代器类型 可以直接用
        auto maxindex = max_element(v.begin(), v.end());
        v.erase(maxindex);
        auto minindex = min_element(v.begin(), v.end());
        v.erase(minindex);
        //求和
        int sum = accumulate(v.begin(), v.end(), 0);
        ans.push_back(sum);
    }
    //搞个sort在反过来输出呗
    sort(ans.begin(), ans.end());
    N = ans.size();
    for (int i = N - K; i < N; i++)
    {
        if (i != N - K)
            cout << ' ';
        cout << fixed << setprecision(3) << 1.0 * ans[i] / (M-2);
    }
    return 0;
}

L2-009 抢红包

题解
没用结构体 用了tuple 试了试
感觉麻烦点。。。
读懂题 模拟就行了
v[0] = {1,2,3};
get可以取出tuple的元素 
get<i>取出第i个元素
get<0>(v[0]) = 1;
cout << get<0>(v[0]);

tie排序方法

#include <iostream>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <tuple>
const int MAX_N = 1e4 + 5;
using namespace std;
int main()
{
    /*
    v[0] = {1,2,3};
    get可以取出tuple的元素 
    get<i>取出第i个元素
    get<0>(v[0]) = 1;
    cout << get<0>(v[0]);
    */
    int N;
    cin >> N;
    //id 是第一个 money 是第二个 cnt 是第三个
    vector<tuple<int, int, int>> v(N + 1);

    for (int i = 1; i <= N; i++)
    {
        int m;
        cin >> m;
        get<0>(v[i]) = i;
        int flag[MAX_N] = {0};
        while (m--)
        {
            int id, money;
            cin >> id >> money;
			//看是不是有人想抢两次 
            if (flag[id] == 1)
                continue;
			//抢的人加钱
            get<1>(v[id]) += money;
			//发红包的人减钱
            get<1>(v[i]) -= money;
			//抢的次数增加
            get<2>(v[id])++;
			//标记
            flag[id] = 1;
        }
    }
    auto cmp = [](tuple<int, int, int> &e1, tuple<int, int, int> e2) {
        //把小于号定住
		//递增 让第一个在前面
		//递减 让第二个在前面
        return tie(get<1>(e2), get<2>(e2), get<0>(e1)) < tie(get<1>(e1), get<2>(e1), get<0>(e2));
    };
    sort(v.begin(), v.end(), cmp);
    for (int i = 0; i <= N; ++i)
    {
        if (get<0>(v[i]) == 0)
            continue;
        cout << get<0>(v[i]) << ' ' << fixed << setprecision(2) << 1.0 * get<1>(v[i]) / 100 << endl;
    }
    return 0;
}

相关标签: PTA真题