zz双周赛3

1-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

解题思路:模拟,只要根据题目对每一个条件进行判断输出即可

注意:对于 ‘ 号,无法直接打出,可再用一次else语句

完整代码如下:

#include <bits/stdc++.h>
using namespace std;
​
int l[4],r[4];
​
int main()
{
    char s[51];
    cin>>s;
    int len=strlen(s);
    for(int i=0; i<len; i++){
        if(s[i]=='1' || s[i]=='Q' || s[i]=='A' || s[i]=='Z' || s[i]=='`') l[0]++;
        else if(s[i]=='2' || s[i]=='W' || s[i]=='S' || s[i]=='X') l[1]++;
        else if(s[i]=='3' || s[i]=='E' || s[i]=='D' || s[i]=='C') l[2]++;
        else if(s[i]=='4' || s[i]=='R' || s[i]=='F' || s[i]=='V' || s[i]=='5' || s[i]=='T' || s[i]=='G' || s[i]=='B') l[3]++;
        else if(s[i]=='6' || s[i]=='Y' || s[i]=='H' || s[i]=='N' || s[i]=='7' || s[i]=='U' || s[i]=='J' || s[i]=='M') r[3]++;
        else if(s[i]=='8' || s[i]=='I' || s[i]=='K' || s[i]==',') r[2]++;
        else if(s[i]=='9' || s[i]=='O' || s[i]=='L' || s[i]=='.') r[1]++;
        else if(s[i]=='0' || s[i]=='P' || s[i]==';' || s[i]=='/' || s[i]=='-' || s[i]=='=' || s[i]=='[' || s[i]==']') r[0]++;
        else r[0]++;
    }
    cout<<l[0]<<endl<<l[1]<<endl<<l[2]<<endl<<l[3]<<endl<<r[3]<<endl<<r[2]<<endl<<r[1]<<endl<<r[0]<<endl;
    return 0;
}
​

1-2

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

输入格式:

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

输出格式:

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

输入样例:

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

2 6

输出样例:

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

4

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

解题思路:可以把所有香肠接成一根香肠,然后进行平均切,如果遇到原切口,那么刀数不用+1

完整代码如下:

#include <bits/stdc++.h>
using namespace std;
​
int main()
{
    int n,m,sum=0;
    cin>>n>>m;
    for(int i=0; i<=n*m; i+=n) if(i%m!=0) sum++;
    cout<<sum;
    return 0;
}
​

1-3

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

输入格式:

第一行是一个整型数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

解题思路:贪心

先把所有活动按照结束时间的长短进行排序,然后对每一个活动进行判断,如果此活动的开始时间大于上一个活动的结束时间,则选择此活动,否则继续对下一个活动进行判断

完整代码如下:

#include <bits/stdc++.h>
using namespace std;
​
const int maxn=1e4+5;
​
struct activity{
    int begin;
    int end; 
}a[maxn];
​
bool cmp(activity s1,activity s2){
    return s1.end<s2.end;
}
​
int main()
{
    int m;
    cin>>m;
    while(m--){
        int n;
        cin>>n;
        for(int i=0; i<n; i++){
            cin>>a[i].begin>>a[i].end;
        }
        sort(a,a+n,cmp);
        int cnt=1,be,ed=a[0].end;
        for(int i=1; i<n; i++){
            if(a[i].begin>=ed){
                ed=a[i].end;
                cnt++;
            }
        }
        cout<<cnt<<endl;
    }
    return 0;
}
​

1-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

解题思路:递归

找到被压缩后的字符后,一层层解压缩

完整代码如下:

#include <bits/stdc++.h>
using namespace std;
​
string jie();
​
int main()
{
    cout<<jie();
    return 0;
}
​
string jie()
{
    int n;
    string s="",t;
    char a;
    while(cin>>a){
        if(a=='['){
            cin>>n;//读入压缩次数 
            t=jie();//记录被压缩的字符串 
            while(n--) s+=t;//解压 
        }else if(a==']') return s;
         else s+=a;
    }
}
//zababzabab [2zabab] [2z[2ab]]

1-5

恰逢 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

解题思路:根据证明可得,大臣左手和右手金币数乘积越大要排的越后面

寻找最大值时要用高精度

完整代码如下:

#include <bits/stdc++.h>
using namespace std;
​
const int maxn=1e5+5;
​
int sum[maxn]={0,1},cnt[maxn],mxn[maxn]={0,1},lens=1,lent=1,lenn=1;
​
struct peo{
    long long l,r;
}per[maxn];
​
bool cmp(peo x,peo y){
    return x.l*x.r<y.l*y.r;
}
​
void mul(long long x);
void div(long long y);
void maxnn();
        
int main()
{
    int n;
    cin>>n;
    cin>>per[0].l>>per[0].r;
    for(int i=1; i<=n; i++) cin>>per[i].l>>per[i].r;
    sort(per+1,per+1+n,cmp);//贪心排序 
    for(int i=1; i<=n; i++){
        mul(per[i-1].l);//高乘 
        div(per[i].r);//高除 
        maxnn();//取最大值 
    }
     for(int i=lenn; i>=1; i--) cout<<mxn[i];
    return 0;
}
​
void mul(long long x)
{
    int t=0;
    for(int i=1; i<=lens; i++) sum[i]*=x;
    for(int i=1; i<=lens; i++){
        t+=sum[i];
        sum[i]=t%10;
        t/=10;
    }
    while(t){
        lens++;
        sum[lens]=t%10;
        t/=10;
    }
}
​
void div(long long y)
{
    memset(cnt,0,sizeof(cnt));
    lent=lens;
    int t=0;
    for(int i=lent; i>=1; i--){
        t*=10;
        t+=sum[i];
        if(t>=y){
            cnt[i]=t/y;
            t%=y;
        }
    }
    while(!cnt[lent]){
        if(lent==1) break;
        lent--;
    }//去除前置的0 
}
​
void maxnn()
{
    if (lent>lenn){
        for(int i=1; i<=lent; i++) mxn[i]=cnt[i];
        lenn=lent;
    }else if(lent==lenn){
        for(int i=lent; i>=1; i--){
            if(mxn[i]<cnt[i]){
                for(int j=1; j<=lent; j++) mxn[j]=cnt[j];
                lenn=lent;
                break;
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值