双周赛 3

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

思路:

        疯狂if。

代码:

 

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
string a;
int cnt[10];
int main()
{
	cin>>a;
	for(int i=0;i<a.length();++i)
	{
		char k=a[i];
		if(k=='`'||k=='1'||k=='Q'||k=='A'||k=='Z')//左手小指
			cnt[1]++;
		if(k=='2'||k=='W'||k=='S'||k=='X')//左手无名指
			cnt[2]++;
		if(k=='3'||k=='E'||k=='D'||k=='C')//左手中指
		    cnt[3]++;
		if(k=='4'||k=='R'||k=='F'||k=='V'||k=='5'||k=='T'||k=='G'||k=='B')//左手食指
			cnt[4]++;
		if(k=='6'||k=='Y'||k=='H'||k=='N'||k=='7'||k=='U'||k=='J'||k=='M')//右手食指
			cnt[5]++;
		if(k=='8'||k=='I'||k=='K'||k==',')//右手中指
			cnt[6]++;
		if(k=='9'||k=='O'||k=='L'||k=='.')//右手无名指
			cnt[7]++;
		if(k=='0'||k=='P'||k==';'||k=='/'||k=='-'||k=='['||int(k)==39||k=='='||k==']')
            //右手小指
			cnt[8]++;
	}
	for(int i=1;i<=8;++i)
	{
		printf("%d\n",cnt[i]);
	}
	return 0;
}

7-2 分香肠

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

输入格式:

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

输出格式:

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

输入样例:

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

2 6

输出样例:

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

4

思路:

       可以将几段香肠看做一根香肠已经被切割n-1次,其中分为有效的和无效的,有效的便不用再次切割。判断平均切割方案中有多少分割点已经被切好了,减去即可。

        解=M-gcd(N,M) 。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m;
int ans;
int gcd(int a,int b)
{
	if(b==0) return a;
	else return gcd(b,a%b);
}
int main()
{
	scanf("%d%d",&n,&m);
	ans=m-gcd(n,m);
	printf("%d",ans);
	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

思路:

        对于没有重合的活动,二者全选最优。对于都可以选但有重合的有两种情况:

                                 

第一种时,选较短的,就能尽可能空出更多的时间来选其他的,相对较优。

第二种时,要选结束时间较早的。综合来看,都可以选但重合的就是选结束时间早的。

我们按结束时间排序活动,用t记录当前已选活动的结束时间,遇到更优的或新参与活动则更新t。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m;
struct node
{
	int st,ed;
}a[10010];
int ans;
bool cmp(node a,node b)
{
	return a.ed<b.ed;
}
int main()
{
	scanf("%d",&m);
	while(m--)
	{
		scanf("%d",&n);
		for(int i=1;i<=n;++i)
			scanf("%d%d",&a[i].st,&a[i].ed);
		sort(a+1,a+n+1,cmp);
		int t=-1;//t为当前已选择活动结束时间
		ans=0;
		for(int i=1;i<=n;++i)
		{
			if(a[i].st>=t)
			{
				t=a[i].ed;
				++ans;
			}
		}
		printf("%d",ans);
		if(m) printf("\n");
	}
	
	return 0;
}

7-4 神秘密码

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

输入格式:

一个字符串。

输出格式:

一个字符串。

输入样例:

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

AC[3FUN]

输出样例:

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

ACFUNFUNFUN

【数据范围】

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

思路:

        从前往后读入存入字符串s中,遇到'['进入递归,cnt记录循环次数,将出现的字母存入字符串a中,回归时不断在s后加上cnt次a,最后输出s。

        对于string类型数据,可以用‘+’来在原字符串后扩展新字符或字符串。

如:string a,b;a+=b表示a串后加上b串;string a;char c;a+=c表示a串后加上字符c。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
string sol()
{
	string s;
	char c;
	while(cin>>c)
	{
		if(c==']') return s;
		else if(c=='[')
		{
			int cnt=0;
			scanf("%d",&cnt);
			string a=sol();
			for(int i=1;i<=cnt;++i)
			{
				s+=a;
			}
		}
		else s+=c;
	}
	return s;
}
int main()
{
	cout<<sol()<<endl;
	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

思路:

        贪心方法较难证明,考验高精乘除。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=1010,MAXM=10010;
struct node
{
	int l,r;
}a[1010];
int pro[MAXM],ans[MAXM],tmp[MAXM];
bool cmp(node a,node b)
{
	return a.l*a.r<b.l*b.r;
}

bool more(int *aa,int *bb)
{//比较,判断是否更新答案
	for(int i=MAXM-1;i>=0;i--){
		if(aa[i]>bb[i]) return 1;
		if(aa[i]<bb[i]) return 0;
	}
	return 0;
}
void times(int *aa,int num)
{//aa*=num高精乘
	for(int i=MAXM-2;i>=0;i--) aa[i]*=num;
	for(int i=0;i<MAXM-1;i++){
		aa[i+1]+=(aa[i]/10);
		aa[i]%=10;
	}
}
void div(int *aa,int *bb,int num)
{//aa除num存入bb中;高精除
	memset(bb,0,sizeof(bb));
	int x=0;
	for(int i=MAXM-1;i>=0;i--){
    	x=x*10+aa[i];
		bb[i]=x/num;
		x%=num;
	}
}
int main()
{
	int n;
	scanf("%d",&n);
	scanf("%d%d",&a[0].l,&a[0].r);
	for(int i=1;i<=n;++i)
	{
		scanf("%d%d",&a[i].l,&a[i].r);
	}
	sort(a+1,a+1+n,cmp);
	
	pro[0]=1;//注意乘积数组初始值为1
	for(int i=0;i<=n;i++)
	{//注意从0开始,国王
		div(pro,tmp,a[i].r);//pro除a[i].r答案在tem上 
		if(more(tmp,ans))//tem>ans则更新答案 
			for(int i=0;i<MAXM;i++) ans[i]=tmp[i];
		times(pro,a[i].l);//自乘
	}
	//去零输出 
	bool f=0;
	for(int i=MAXM-1;i>=0;i--)
	{
		if(!f)
		{
			if(ans[i]) f=1;
			else continue;
		}
		printf("%d",ans[i]);
	}
	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值