第三次周赛

T1:打字

题目:

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

输入格式:

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

输出格式:

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

思路:

模拟一遍,然后用数组存储对应的字母,如果字母X在数组A中,那么A++

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

string f[]={"1QAZ","2WSX","3EDC","4RFV5TGB","6YHN7UJM","8IK,","9OL.","0P;/'][-="};
string x;
int cnt[9],L,flag;

int main()
{
    cin>>x;
    L=x.length();
    for(int i=0;i<L;i++){
        flag=0;
        for(int j=0;j<8;j++){
            int s=f[j].length();
            for(int k=0;k<s;k++){
                if(f[j][k]==x[i]){
                    cnt[j]++;
                    flag=1;
                    break;
                }
                if(flag)break;
            }
        }
    }
    for(int i=0;i<8;i++){
        cout<<cnt[i]<<endl;
    }
    return 0;
}

T2:分香肠

题目:

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

输入格式:

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

输出格式:

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

思路:

假设有n根肠,就可以看作一根已经被切过n-1次的一根肠,然后一根肠分给m个人,要切m-1次,然后检验一下哪几刀是原本我们就已经切过的(利用向上和向下取整函数)。

#include<bits/stdc++.h>
using namespace std;
int a,b;
double eps=1e-6;
int main()
{
    cin>>a>>b;
    int ans=b-1,cnt=b-1;
    for(int i=1;i<=cnt;i++){
        double x=a*(i*1.0/b);
        
        if(x-floor(x)<eps||ceil(x)-x<eps)ans--;
    }
    cout<<ans;
    return 0;
}

T3:会议安排

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

输入格式:

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

输出格式:

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

思路:

想要参加更多的会议,就要选择结束时间最短的,然后自定义结构体排序一遍,对于能够参加的会议(指当前会议结束时间不早于下一会议开始时间)ans++就行

#include<bits/stdc++.h>
using namespace std;
int m,n,cnt;
struct T{
    int st,end;
}t[100005];
bool cmp(T a,T b){
    return a.end<b.end;
}
int main()
{
    cin>>m;
    while(m--){
        cin>>n;
        cnt=1;
        for(int i=1;i<=n;i++){
            cin>>t[i].st>>t[i].end;
        }
        sort(t+1,t+1+n,cmp);
        int now=t[1].end;
        for(int i=2;i<=n;i++){
            if(now<=t[i].st){//判断是否能参加
                cnt++;
                now=t[i].end;
            }
        }
        cout<<cnt<<endl;
    }
}

T4:神秘密码

题目

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

输入格式:

一个字符串。

输出格式:

一个字符串。

输入样例:

AC[3FUN]

输出样例:

ACFUNFUNFUN

思路:

借鉴别人的递归思路(原本我用的栈模拟,感觉不大好做)

#include<bits/stdc++.h>
using namespace std;
string read()
{
	string S,s;
    int n;
	char c;
	while (cin>>c)//连续读入
	{
		if (c=='[')//如果是左括号的话,后面必然接有一个数字
		{
			cin>>n;
			s=read();
			while(n--)S+=s;
		}
		else if(c==']') return S;//如果是右括号表示当前压缩过程已经结束了
		else S+=c;//读入的是单个字符直接加上
	}
}
int main()
{
    cout<<read();
	return 0;
}

T4:国王游戏

题目:

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

输入格式:

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

输出格式:

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

思路:贪心+高精度

贪心:

简而言之:想要最大的最小,就是要将左右手乘积最小的放在前面

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

typedef long long LL;

const int inf = 1 << 30;
int n;
struct node{
	int L,R;
}t[10005];
bool cmp(node a,node b){return a.L*a.R<b.L*b.R;} 

int res[20005];
string multi(string p,string q){
	reverse(p.begin(),p.end());reverse(q.begin(),q.end());
	memset(res,0,sizeof res);
	for(int i=0;i<p.size();i++){
		for(int j=0;j<q.size();j++){
			res[i+j]+=(p[i]-'0')*(q[j]-'0');
		}
	}
	for(int i=0;i<p.size()+q.size();i++){
		if(res[i]>=10){
			res[i+1]+=res[i]/10;
			res[i]%=10;
		}
	}
	
	string restr="";bool fg=1;
	for(int i=p.size()+q.size()-1;i>=0;i--){
		if(res[i]==0&&fg)continue;
		else{
			fg=0;
			restr+=res[i]+'0';
		}
	}
	return restr;
}

string MAX(string p,string q){
	if(p.size()!=q.size())return p.size()>q.size()?p:q;
	return p>q?p:q;
}

int dvs[20005],dvres[20005];
string div(string a,int b){
	memset(dvs,0,sizeof(dvs));
	memset(dvres,0,sizeof(dvres));
	for(int i=0;i<a.size();i++)dvs[i+1]=a[i]-'0';
	int bs=0;
	for(int i=1;i<=a.size();i++){
		dvres[i]=(bs*10+dvs[i])/b;
		bs=(bs*10+dvs[i])%b;
	}
	int lc=1;
	while(dvres[lc]==0&&lc<a.size())++lc;
	string div_ans="";
	for(int i=lc;i<=a.size();i++)div_ans+=dvres[i]+'0';
	return div_ans;
}

string convert(int y){
	string s="";
	while(y){
		s+=y%10+'0';
		y/=10;
	}
	reverse(s.begin(),s.end());
	return s;
}

int main(){

	cin>>n;
	for(int i=0;i<=n;i++)cin>>t[i].L>>t[i].R;
	sort(t+1,t+n+1,cmp);
	string ans="0",T=convert(t[0].L);
	for(int i=1;i<=n;i++){
		ans=MAX(ans,div(T,t[i].R));//非高精度版:ans=max(ans,T/t[i].R)
		T=multi(T,convert(t[i].L));//非高精:T*=t[i].L
	}
	cout<<ans<<endl;

	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值