第三周双周赛题解

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

一道简单的模拟题,用一个数组figure[i]表示第i根手指的敲击次数,遍历字符串的每个字符,每种情况分类讨论就可以。

完整代码如下:

#include<iostream>
using namespace std;
int figure[8];
int main(){
    string a;
    cin>>a;
    for(int i=0;i<a.length();i++){   //每种情况分类讨论
        if(a[i]=='1'||a[i]=='A'||a[i]=='Q'||a[i]=='Z'){
            figure[0]++;
        }
        else if(a[i]=='2'||a[i]=='X'||a[i]=='W'||a[i]=='S'){
            figure[1]++;
        }
        else if(a[i]=='3'||a[i]=='E'||a[i]=='D'||a[i]=='C'){
            figure[2]++;
        }
        else if(a[i]=='4'||a[i]=='5'||a[i]=='R'||a[i]=='T'||a[i]=='G'||a[i]=='F'||a[i]=='B'||a[i]=='V'){
            figure[3]++;
        }
        else if(a[i]=='6'||a[i]=='7'||a[i]=='Y'||a[i]=='U'||a[i]=='H'||a[i]=='J'||a[i]=='N'||a[i]=='M'){
            figure[4]++;
        }
        else if(a[i]=='8'||a[i]=='I'||a[i]=='K'||a[i]==','){
            figure[5]++;
        }
        else if(a[i]=='9'||a[i]=='O'||a[i]=='L'||a[i]=='.'){
            figure[6]++;
        }
        else{
            figure[7]++;
        }
    }
    for(int i=0;i<8;i++){
        cout<<figure[i]<<endl;  //输出即可
    }
    return 0;
}

2.分香肠

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

输入格式:

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

输出格式:

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

输入样例:

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

2 6

输出样例:

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

4

这道题需要一定的想法:我们可以将所有的香肠拼接在一起,那么我们就可以把它看成一根香肠。这样,我们就只需要将这一整香肠切成同等份就可以了。但是我们需要判断一下每次切是不是真的在“切”(说起来真的好奇怪),因为这些连在一起的香肠中间本来就是没连在一起的,所以我们需要判断一下。但是我们还有一个更简单的公式:n=m-_gcd(n,m),这里不予证明。

完整代码如下:

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n,m,ans=0;
	cin>>n>>m;
	ans=m-__gcd(n,m);	
	cout<<ans;
	return 0;
}

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

因为一段时间只能最多举办一个活动,所以我们如果想尽可能地多安排活动该怎么做呢?

显然,我们需要将结束时间早的活动安排到前面,因为一个活动的开始是依赖上个活动的结束时间的,所以我们可以将这些活动按照结束时间从早到晚排序,然后,我们要依次比较这些活动的时间段是否重叠。即我们需要定义一个起点,第一个起点显然是第一个活动的结束时间,如果下个活动的开始时间小于这个起点,那么就代表这个活动与最开始的这个活动时间有冲突,不能安排,如果没有冲突就代表可以,并把下个起点安排到这个活动的结束时间。以此类推,最终的结果也就为最多能安排的活动数量。

完整代码如下:

#include<iostream>
#include<math.h>
using namespace std;
struct o{
    int time1;
    int time2;
};
o oarr[105][10005];      //用o结构体表示活动
int n,n1,ans[1000005],len=0;
void quicksort(int now,int l,int r){  //这里我用了快排来代替sort函数来进行排序
    if(l>r){
        return;
    }
    int l_num,l_point,r_point,temp;
    l_point=l;
    r_point=r;
    l_num=oarr[now][l].time2;
    while(l<r){
        while(oarr[now][r].time2>=l_num&&r>l){
            r--;
        }
        while(oarr[now][l].time2<=l_num&&r>l){
            l++;
        }
        swap(oarr[now][l],oarr[now][r]);
    }
    swap(oarr[now][l_point],oarr[now][l]);
    quicksort(now,l_point,l-1);
    quicksort(now,r+1,r_point);
}
void judge(int now){  //判断每个活动是否可以取
    int ret=1;
    int start=oarr[now][0].time2;  //初始化起点为第一个活动的结束时间
    for(int i=1;i<n1;i++){
        if(oarr[now][i].time1>=start){
            ret++;
            start=oarr[now][i].time2;
        }
    }
    ans[len]=ret;
    len++;  //记录数量
}
int main(){
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>n1;
        for(int j=0;j<n1;j++){
            cin>>oarr[i][j].time1;
            cin>>oarr[i][j].time2;
        }            
        quicksort(i,0,n1-1);
        judge(i);
    }
    for(int i=0;i<n;i++){
        cout<<ans[i]<<endl;
    }
    return 0;
 }

4.神秘密码

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

输入格式:

一个字符串。

输出格式:

一个字符串。

输入样例:

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

AC[3FUN]

输出样例:

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

ACFUNFUNFUN

【数据范围】

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

我真的不明白为什么我在洛谷提交这道题的代码后明明通过了,在pta提交却通过不了qwq,只能换一种写法

这里的压缩字符很明显要用到递归的思想,怎么用到呢?

例如[4[4ER[4RR[4TY]]]]这个压缩的字符,我们从头开始遍历,我们第一个能发现要对[4[4ER[4RR[4TY]]]]这个字符进行解压缩,然后我们继续往下看就会发现需要对[4ER[4RR[4TY]]]这个字符进行解压缩,紧接着,我又会发现需要对[4RR[4TY]]这个字符进行解压缩,最后是[4TY]这个字符。然后我们对[4TY]这个字符解压缩后就到了下一层,解压缩后的字符为:[4RRTYTYTYTY],然后对这个字符进行解压缩并丢给下一层,依次类推。

显然我们这里可以发现,我们每发现一个”[“就代表我们要达到下一层,并且每一层一开始必定会输入这一层的字符压缩的次数,如果发现字符,那么这一层的字符就是我们发现的这些字符。所以我们可以根据这这些特性写出代码。

完整代码如下:

#include<bits/stdc++.h>
using namespace std;
string read()
{
	int num;
	string ans="",str;  //ans为最终的结果字符,str为被压缩的字符
	char c;
	while (cin>>c)  //不停输入c
	{
		if (c=='['){  //如果发现"["
			cin>>num;  //那么下一个字符必定是数字,也就是被压缩的次数
			str=read();  //递归调用read()函数来进行输入下面的字符
			while (num--){  
              ans+=str;  //进行解压缩
            } 
		}
		else    //如果不是"[”
		{
			if (c==']') {  //如果是"]"就要将解压缩后的字符串丢给下一层
                return ans;
            }
		    else {
                ans+=c;  //加上其他的字符
            }
		}
	}
}
int main()
{
	cout<<read(); 
	return 0;
}

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

说实话,如果我不看题解,我死都不会想到是这样的答案。

这里我就不细讲了,(因为我也不会,我也是看了题解才知道怎么做),直接上图看题解吧:

在这里插入图片描述

在这里插入图片描述
所以我们需要将每位成员按照左手数字与右手数字相乘的乘积按从小到大排序,然后计算每个人能得到的钱,取最大的就可以得到答案了。(但需要注意:因为这里的数据有亿点点大,所以我们还需要采用高精度qwq)

完整注释代码如下:

#include<bits/stdc++.h>
using namespace std;
struct people{
	int l;
	int r;
	int ans;  //ans为左右手数字的乘积
}arr[1005];   //用arr存放每位大臣的信息
bool cmp(const people &p1,const people &p2){
	return p1.ans<p2.ans;  //让每位大臣按照每位大臣的左右手乘积从小到大排序
}
int numarr[10010],len_num2=1,ans[10010],len_ans=1,numshuzu[10010],finalans[10010];
string money[1005];
int turn(int len){   //模拟进位
	for(int i=0;i<len;i++){
		if(numshuzu[i]>=10){
			numshuzu[i+1]+=numshuzu[i]/10;
			numshuzu[i]%=10;
		}
		if(numshuzu[len]>0){
			len++;
		}
	}
	return len;
}
string chu(int len,int chushu){  //高精度除法
	int a=0,len_finalans=0;
	string ans1;
	for(int i=0;i<len;i++){
		a=a*10+ans[i];
		if(a>=chushu){
			finalans[len_finalans++]=a/chushu;
			ans1+=to_string(a/chushu);
			a%=chushu;
		}
		else if(a<chushu&&len_finalans>0){
			ans1+="0";
		}
	}
	return ans1;  //返回结果的字符
}
void cheng(int num,int chushu){   //高精度乘法
	memset(numshuzu,0,sizeof(numshuzu));
	string a=to_string(num);
	int len_num1=a.length(),len_zong=0;
	for(int i=0;i<len_num1;i++){
		numarr[i]=a[i]-'0';
	}
	for(int i=len_ans-1;i>=0;i--){			
		len_zong=len_ans-1-i;	
		for(int a=len_num1-1;a>=0;a--){
			numshuzu[len_zong++]+=ans[i]*numarr[a];
		}		
	}
	len_ans=turn(len_zong);
	for(int i=len_ans-1;i>=0;i--){
		ans[len_ans-1-i]=numshuzu[i];
	}
}
int main(){
	long long num,l,r,sum=1;
	ans[0]=1;
	cin>>num>>l>>r;
	arr[0].l=l;
	arr[0].r=r;
	for(int i=1;i<=num;i++){
		cin>>arr[i].l>>arr[i].r;
		arr[i].ans=arr[i].l*arr[i].r;  //在输入时顺便计算乘积
	}
	sort(arr+1,arr+num+1,cmp);  //进行排序
	for(int i=1;i<=num;i++){
		cheng(arr[i-1].l,arr[i].r);   //进行累乘
	}
	if(chu(len_ans,arr[num].r)==""){  
		cout<<"1"<<endl;
	}
	else{
		cout<<chu(len_ans,arr[num].r);  //输出最后的结果
	}
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值