2023年SF-X菁英挑战赛(科技赛道-编程方向)半决赛(4题)

比赛概况

4个题目,第一题签到题,第二题是一个考面向对象的题目,第三题一眼最短路,但是好久没复习了,忘记代码了,第四题贪心
题目概况

第一题 签到

题目简介

题目简介

解题思路

直接拿三个字符串分别记录三种快递的情况,输出即可

代码

#include <iostream>
#include <string>
using namespace std;

int main() {
    string s;
    while (cin >> s) { // 注意 while 处理多个 case
        string a = "", b = "", c = "";
        for(int i = 0; i < s.size(); i ++){
            if(s[i] >= 'a' && s[i] <= 'z') a+=s[i];
            else if(s[i] >= 'A' && s[i] <= 'Z') b+=s[i];
            else c += s[i];
        }
        cout << a << endl;
        cout << b << endl;
        cout << c << endl;
    }
}

第二题 面向对象

题目简介

本题目是给出主函数,完成功能函数即可
题目简介
示例一:
输入:

7
punish
bob 5 3
punish
bob 5 1
relieve
alice 3
relieve
alice 5
query
1 20
query
2 20
getByUserId
5
输出
1_5_bob_3
2_5_alice_0
1_5_bob_3
2_5_alice_0
1
-1
-1
2
说明
示例二
输入

4
punish
bob 5 1
punish
bob 5 3
relieve
alice 5
punish
bob 5 3
输出
1
2
3
4

解题思路

思路比较简单,看明白题意写就行了,就是要先读懂题目意思以及代码,逻辑理顺了不算很难

代码

#include <bits/stdc++.h>
using namespace std;

int cnt = 0;
struct node{
	string name;
	int id, level;
};
vector<node>v;

class HistoryResult
{
public:
	HistoryResult(int id, int userId, string operatorUserName, int status)
	{
		this->id = id;
		this->userId = userId;
		this->operatorUserName = operatorUserName;
		this->status = status;
	}

	int getId() const
	{
		return id;
	}

	int getUserId() const
	{
		return userId;
	}

	string getOperatorUserName() const
	{
		return operatorUserName;
	}

	int getStatus() const
	{
		return status;
	}

private:
	int id;
	int userId;
	string operatorUserName;
	int status;
};

class Main
{
public:

	/**
     * 查询处罚记录,记录按照id升序排序
     *
     * @param pageNo   第几页
     * @param pageSize 页数大小
     * @return 查询结果
     */
	vector<HistoryResult> query(int pageNo, int pageSize)
	{
		vector<HistoryResult> a;
		int minn;
		if(v.size() < pageNo*pageSize) minn = v.size();
		else minn = pageNo*pageSize;
		for(int i = (pageNo-1)*pageSize; i < minn; i ++){
			HistoryResult x(i+1, v[i].id, v[i].name, v[i].level);
			// x->Id = i+1;
			// x->UserId = v[i].id;
			// x->OperatorUserName = v[i].name;
			// x->Status = v[i].level;
			a.push_back(x);
		}
		return a;
	}

 	/**
     * 查询某个用户的处罚记录,记录按照id升序排序
     *
     * @param userId 用户
     * @return 处罚记录
     */
	vector<HistoryResult> getByUserId(int userId)
	{
		vector<HistoryResult> a;
		for(int i = 0; i < v.size(); i ++){
			if(v[i].id == userId){
				HistoryResult x(i+1, v[i].id, v[i].name, v[i].level);
				// x->Id = i+1;
				// x->UserId = v[i].id;
				// x->OperatorUserName = v[i].name;
				// x->Status = v[i].level;
				a.push_back(x);
			}
		}
		return a;
	}

	/**
     * 处罚操作, 如果用户已经有被处罚了,新的处罚不能低于当前处罚等级才能生效
     *
     * @param operatorUserName 操作者的名字
     * @param userId           处罚的用户
     * @param punishStatus     处罚类型
     * @return 返回处罚的记录id, 处罚不成功返回-1
     */
	int punish(string operatorUserName, int userId, int punishStatus)
	{
		node x;
		int maxx = 0;
		for(int i = 0; i < v.size(); i ++){
			if(userId == v[i].id) maxx = v[i].level;
		}
		if(punishStatus >= maxx){
			x.id = userId;
			x.level = punishStatus;
			x.name = operatorUserName;
			v.push_back(x);
			return v.size();
		}
		return -1;
	}

	 /**
     * 解除当前处罚
     *
     * @param operatorUserName 操作者的名字
     * @param userId           解除处罚的用户
     * @return 如果当前用户正在被处罚中,解除当前处罚,返回处罚记录id,如果用户没有被处罚,返回-1表示解除处罚非法
     */
	int relieve(string operatorUserName, int userId)
	{
		node x;
		int minn = 99999999;
		for(int i = 0; i < v.size(); i ++){
			if(userId == v[i].id) minn = v[i].level;
		}
		if(minn == 99999999) return -1;
		if(minn){
			x.id = userId;
			x.level = 0;
			x.name = operatorUserName;
			v.push_back(x);
			return v.size();
		}
		return -1;
	}
};

int main()
{
	Main main;
	int opNum;
	cin >> opNum;
	cin.ignore();
	vector<HistoryResult> printHistory;
	vector<int> printOperators;
	for (int i = 0; i < opNum; ++i)
	{
		string op;
		getline(cin, op);
		string data;
		getline(cin, data);
		if (op == "punish")
		{
			std::istringstream iss(data);
			std::string operatorUserName;
			int userId;
			int punishStatus;
			iss >> operatorUserName >> userId >> punishStatus;
			printOperators.push_back(main.punish(operatorUserName, userId, punishStatus));
		}
		else if (op == "relieve")
		{
			std::istringstream iss(data);
			string operatorUserName;
			int userId;
			iss >> operatorUserName >> userId;
			printOperators.push_back(main.relieve(operatorUserName, userId));
		}
		else if (op == "getByUserId")
		{
			std::istringstream iss(data);
			int userId;
			iss >> userId;
			vector<HistoryResult> results = main.getByUserId(userId);
			if (!results.empty())
			{
				printHistory.insert(printHistory.end(), results.begin(), results.end());
			}
		}
		else if (op == "query")
		{
			std::istringstream iss(data);
			int pageNo, pageSize;
			iss >> pageNo >> pageSize;
			vector<HistoryResult> results = main.query(pageNo, pageSize);
			if (!results.empty())
			{
				printHistory.insert(printHistory.end(), results.begin(), results.end());
			}
		}
		else
		{
			cout << "错误的输入" << endl;
		}
	}
	for (const HistoryResult &result : printHistory)
	{
		cout << result.getId() << "_" << result.getUserId() << "_"
			 << result.getOperatorUserName() << "_" << result.getStatus() << endl;
	}
	for (int operatorResult : printOperators)
	{
		cout << operatorResult << endl;
	}
	return 0;
}

第三题 最短路

题目简介

题目简介

解题思路

题目大意就是n个点,m条边,有一个魔法,不可以在1和n用,可以用一次,可以随便走花费x,问1到n最短路。
一眼最短路,dijkstra套模板求一个最短路,1最近的点+n最近的点+x,这两个值取min即可,-1的情况,没有联通1或n输出-1。

代码

#include<bits/stdc++.h>
using namespace std;
#define Pair pair<int, int>
#define ll long long
const int maxn = 100005;
const int maxm = 200005;
#define inf 0x3f3f3f3f
#define met(a, b) memset(a, b, sizeof(a));

ll dist[maxn];
int head[maxn];
bool vis[maxn];
struct node{
    int next, to;
    ll w;
}edge[maxm];
int n, m, x, cnt;

void init()
{
    for(int i = 0; i <= n; i++) dist[i] = LONG_LONG_MAX;
    met(head, -1);
    met(vis, false);
    cnt = 0;
}

void add(int u, int v, ll w){
    edge[cnt].next = head[u];
    edge[cnt].to = v;
    edge[cnt].w = w;
    head[u] = cnt++;
}

void dijkstra(int v)
{
    priority_queue<Pair, vector<Pair>, greater<Pair> >q;
    dist[v] = 0;
    q.push(Pair(0, v));
    while(!q.empty()){
        Pair p;
        p = q.top();
        q.pop();
        int u = p.second;
        if(vis[u]) continue;
        vis[u] = true;
        for(int i = head[u]; ~i; i = edge[i].next){
            node e = edge[i];
            if(dist[e.to] > e.w + dist[u]){
                dist[e.to] = dist[u] + e.w;
                q.push(Pair(dist[e.to], e.to));
            }
        }
    }
}

int main() {
    while (cin >> n >> m >> x) { // 注意 while 处理多个 case
        ll s = inf, e = inf;
        init();
        for(int i = 0; i < m; i ++){
            int u, v;
            ll w;
            cin >> u >> v >> w;
            if(u == 1 || v == 1) s = min(w, s);
            if(u == n || v == n) e = min(w, e);
            add(u, v, w);
            add(v, u, w);
        }
        if(s == inf || e == inf){
            cout << -1 << endl;
            continue;
        }
        dijkstra(1);
        cout << min(dist[n], s+e+x) << endl;
    }
}

第四题 贪心

题目简介

题目简介

解题思路

贪心,优先按照工资升序排序,然后按照满意度降序排序,优先完成跨城运输项目即可

代码

#include <bits/stdc++.h>>
using namespace std;
#define ll long long
struct node{
    char type;
    ll a, b;
}a[100005];

bool cmp(node x, node y){
    return x.a < y.a || (x.a == y.a && x.b > y.b);
}

int main() {
    ll n, x, y;
    while (cin >> n >> x >> y) { // 注意 while 处理多个 case
        ll A = 0, B = 0;
        for(ll i = 0; i < n; i ++){
            cin >> a[i].type >> a[i].a >> a[i].b;
            if(a[i].type == 'A') A ++;
            else B ++;
        }
        if(B < y || x + y > n){
            cout << -1 << endl;
            continue;
        }
        sort(a, a+n, cmp);
        ll ans = 0, cnt = 0;
        for(ll i = 0; i < n; i ++){
            if(a[i].type == 'B'){
                a[i].type = 'C';
                ans += a[i].b;
                cnt ++;
            }
            if(cnt == y) break;
        }
        for(ll i = 0; i < n; i ++){
            if(a[i].type != 'C'){
                ans+=a[i].b;
                cnt ++;
            }
            if(x + y == cnt) break;
        }
        cout << ans << endl;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值