用老师讲的方法做的 题解

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

发布了116 篇原创文章 · 获赞 27 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_45653525/article/details/104703537