第三次双周赛

本文探讨了提高打字效率的技巧,通过正确使用手指布局减少打字时间,并提供了相关练习。此外,还介绍了如何有效地分配香肠以平均分给多人,以及解决会议时间冲突的策略。同时,阐述了解压缩字符串的方法和避免国王游戏中大臣获得过多金币的策略。涉及问题包括字符串处理、数学算法和逻辑规划。
摘要由CSDN通过智能技术生成

7-1 打字

如果你仍然再用二指禅打字,那我建议你重新学习打字,这样你打字会更快,感觉更舒适和愉快。

有很多网站教授正确的打字。下图描述了基本原理: 用同一手指按压颜色相同的键。黄色键需要用小指按压,蓝色的用无名指,绿色的用中指,红色的用食指。

另外,左手按键盘的左侧(从左侧的5、T、G、B键开始)右手按压右侧(从右侧的键6、Y、H、N开始)。拇指负责空格键。

图片描述的键盘是美式键盘。

现在,给出一段长度为 len(1≤len≤50) 的字符串,请你计算如果正确打出这个字符串,每个手指敲击键盘的次数。

输入格式:

输入为一行,一个由大写字母、数字和特殊符号组成的字符串(不包括空格,不需要管图片中未显示的按键)。

输出格式:

输出8行,表示左手小指、无名指、中指、食指以及右手食指、中指、无名指、小指敲击键盘的次数。

输入样例1:

AON=BOO; 

输出样例1:

1
0
0
1
1
0
3
2

输入样例2:

PRINT'NY'[NASLA] 

输出样例2:

2
1
0
2
4
1
1
5

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

题解:

就穷举了一下

#include<iostream>
#include<string>
using namespace std;
int main() {
	int jishu[8] = { 0 };
	string a;
	getline(cin, a);
	for (int e = 0; e < a.size(); e++) {
		if (a[e] == '1'||a[e] == 'Q'||a[e] == 'A'||a[e] == 'Z') {
			jishu[0]++;
		}
		if (a[e] == '2'||a[e] == 'W'||a[e] == 'S'||a[e] == 'X') {
			jishu[1]++;
		}
		if (a[e] == '3'||a[e] == 'E'||a[e] == 'D'||a[e] == 'C') {
			jishu[2]++;
		}
		if (a[e] == '4'||a[e] == 'R'||a[e] == 'F'||a[e] == 'V'||a[e] == '5'||a[e] == 'T'||a[e] == 'G'||a[e] == 'B') {
			jishu[3]++;
		}
		if (a[e] == '6'||a[e] == 'Y'||a[e] == 'H'||a[e] == 'N'||a[e] == '7'||a[e] == 'U'||a[e] == 'J'||a[e] == 'M') {
			jishu[4]++;
		}
		if (a[e] == '8' || a[e] == 'I' || a[e] == 'K' || a[e] == ',') {
			jishu[5]++;
		}
		if (a[e] == '9' || a[e] == 'O' || a[e] == 'L' || a[e] == '.') {
			jishu[6]++;
		}
		if (a[e] == '0' || a[e] == 'P' || a[e] == ';' || a[e] == '/' || a[e] == '-' || a[e] == '[' || a[e] == '\'' || a[e] == '=' || a[e] == ']') {
			jishu[7]++;
		}

	}
	for (int e = 0; e < 8; e++) {
		cout << jishu[e] << endl;
	}
	system("pause");
	return 0;
}

 

7-2 分香肠

有 N 根完全相同的香肠, 现在要平均分给 M 个客人。 问最少需要切几刀才能将其平均分给客人(不能多个香肠一起切)。

输入格式:

两个整数 N(1≤N≤105) 和 M(1≤M≤105)

输出格式:

一个整数,表示要切的刀数

输入样例:

在这里给出一组输入。例如:

2 6

输出样例:

在这里给出相应的输出。例如:

4

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

题解:

这道题当时想的太复杂了,分各种情况讨论,但最后都因为考虑不全面所以没对,主要还是思路的问题。可以直接把所有的香肠算作一根,然后按道理来说因为有m个人,所以需要切m-1刀,但是因为可能正好切在两根香肠的连接处,所以还需要减去多切的刀数,即两数的最大公约数。

#include<iostream>
using namespace std;
int gcd(int a,int b)
{
    if(b==0) return a;
    else return gcd(b,a%b);
}
int main()
{
    int N,M;
    cin>>N>>M;
    cout<<M-gcd(M,N)<<endl;
    return 0;
}

7-3 h0145. 会议安排

学校的礼堂每天都会有许多活动,有时间这些活动的计划时间会发生冲突,需要选择出一些活动进行举办。小刘的工作就是安排学校礼堂的活动,每个时间最多安排一个活动。现在小刘有一些活动计划的时间表,他想尽可能的安排更多的活动,请问他该如何安排。

输入格式:

第一行是一个整型数m(m<100)表示共有m组测试数据。
每组测试数据的第一行是一个整数n(1<n<10000)表示该测试数据共有n个活动。
随后的n行,每行有两个正整数Bi,Ei(0<=Bi,Ei<10000),分别表示第i个活动的起始与结束时间(Bi<=Ei)

输出格式:

对于每一组输入,输出最多能够安排的活动数量。
每组的输出占一行

输入样例:

在这里给出一组输入。例如:

2
2
1 10
10 11
3
1 10
9 11
11 20

输出样例:

在这里给出相应的输出。例如:

2
2

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

题解:

录入数据后用sort将数据按照结束时间顺序排序,然后for遍历数据,能塞进去就塞,塞不进去就下一个,最后输出统计的数据。

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
struct jilu {
	int st;
	int ed;
};
vector<jilu>G;
bool cmp(jilu a, jilu b)
{
	return a.ed < b.ed;
}
int main()
{
	int T;
	cin >> T;
	for (int e = 0; e < T; e++) {
		int n, cishu = 0;
		cin >> n;
		G.resize(n + 1);
		for (int i = 1; i <= n; i++)
		{
			cin >> G[i].st >> G[i].ed;
		}
		sort(G.begin() + 1, G.begin() + 1 + n, cmp);
		int now = 0;
		for (int i = 1; i <= n; i++)
		{
			if (G[i].st >= now)
			{
				now = G[i].ed;
				cishu++;
			}
		}
		cout << cishu << endl;
	}
	system("pause");
	return 0;
}

4-神秘密码

传说二战时X国收到了上帝的一串密码,只有解开密码,才能阻止战争的继续进行,世界才会恢复和平。解开密码的第一道工序就是解压缩密码,上帝对于连续的若干个相同的子串"X"会压缩为"[DX]"的形式(D是一个整数且1<=D<=99),比如说字符串"CBCBCBCB"就压缩为"[4CB]"或者"[2[2CB]]",类似于后面这种压缩之后再压缩的称为二重压缩。如果是"[2[2[2CB]]]"则是三重的。现在我们给你上帝发送的密码,请你对其进行解压缩。

输入格式:

一个字符串。

输出格式:

一个字符串。

输入样例:

在这里给出一组输入。例如:

AC[3FUN]

输出样例:

在这里给出相应的输出。例如:

ACFUNFUNFUN

【数据范围】

解压后的字符串长度在 20000 以内,最多只有十重压缩。保证只包含数字、大写字母、[ 和 ]

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

题解:

利用递归进行读取,如果是字符,就加到结果字符串a上,如果是[,则进入一个新的循环,直到接收到]后退出当前函数,返回上一个函数。

#include<bits/stdc++.h>
using namespace std;
string code()
{
	string a, X;
	char c;
	int D;
	while (cin >> c)
	{
		if (c == '[')
		{
			cin >> D;
			X = code();
			while (D--) a += X;
			return a;
		}
		else if (c == ']')
		{
			return a;
		}
		else a += c;
	}
}
int main()
{
	cout << code();
	system("pause");
	return 0;
}

7-5 h0114.国王游戏

恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏。
首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。
然后,让这 n 位大臣排成一排,国王站在队伍的最前面。
排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:
排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。
国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。
注意,国王的位置始终在队伍的最前面。

输入格式:

第一行包含一个整数 n(1≤n≤1000),表示大臣的人数。
第二行包含两个整数 a (0<a)和 b(b<10000),之间用一个空格隔开,分别表示国王左手和右手上的整数。
接下来 n 行,每行包含两个整数 a 和 b,之间用一个空格隔开,分别表示每个大臣左手和右手上的整数。

输出格式:

输出只有一行,包含一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得的金币数。

输入样例:

在这里给出一组输入。例如:

3
1 1
2 3
7 4
4 6

输出样例:

在这里给出相应的输出。例如:

2

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

题解:

根据题解说明,按照左右手数字乘积从小到大排列即为最佳顺序,则只需要开始录入数据,sort排序后利用大数运算将最后一人前所有人的左手数乘在一起,然后除以最后一人的右手数即可得出答案。

#include <bits/stdc++.h>
using namespace std;
struct t
{
    int l, r, j;
};
bool cc(t a, t b)
{
    return a.j < b.j;
}
vector<t>s;
int main()
{
    int n, l, r;
    cin >> n >> l >> r;
    s.resize(n);
    for (int i = 0; i < n; i++)
    {
        cin >> s[i].l >> s[i].r;
        s[i].j = s[i].l * s[i].r;
    }
    sort(s.begin(), s.begin() + n, cc);
    int num[100000], top = 1;
    memset(num, 0, sizeof(num));
    do
    {
        num[top++] = l % 10;
        l /= 10;
    } while (l != 0);
    top--;
    for (int i = 0; i < n - 1; i++)
    {
        for (int j = 1; j <= top; j++)
        {
            num[j] *= s[i].l;
        }
        for (int j = 1; j <= top; j++)
        {
            num[j + 1] += num[j] / 10;
            num[j] %= 10;
        }
        if (num[top + 1] != 0)
        {
            top++;
            while (num[top] >= 10)
            {
                num[top + 1] = num[top] / 10;
                num[top] %= 10;
                top++;
            }
        }
        if (num[top] == 0)
        {
            top--;
        }
    }
    for (int i = top; i >= 1; i--)
    {
        num[i - 1] += num[i] % s[n - 1].r * 10;
        num[i] /= s[n - 1].r;
    }
    while (num[top] == 0)
    {
        top--;
    }
    if (top == 0)
    {
        cout << "1"; return 0;
    }
    for (int i = top; i >= 1; i--)
    {
        cout << num[i];
    }
    system("pause");
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唏嘘南溪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值