NEUQACM第三次双周赛

7-1 打字

分数 20

作者 neuqAcmClub

单位 东北大学秦皇岛分校

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

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

另外,左手按键盘的左侧(从左侧的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 <bits/stdc++.h>
using namespace std;

int n[9];

int main()
{
    char s;
    while(cin>>s)
    {
        if(s=='1'||s=='Q'||s=='A'||s=='Z')n[1]++;
        else if(s=='2'||s=='W'||s=='S'||s=='X')n[2]++;
        else if(s=='3'||s=='E'||s=='D'||s=='C')n[3]++;
        else if(s=='4'||s=='R'||s=='F'||s=='V')n[4]++;
        else if(s=='5'||s=='T'||s=='G'||s=='B')n[4]++;
        else if(s=='6'||s=='Y'||s=='H'||s=='N')n[5]++;
        else if(s=='7'||s=='U'||s=='J'||s=='M')n[5]++;
        else if(s=='8'||s=='I'||s=='K'||s==',')n[6]++;
        else if(s=='9'||s=='O'||s=='L'||s=='.')n[7]++;
        else n[8]++;
    }
    for(int i=1;i<=8;i++)
    {
        cout<<n[i];
        if(i!=8)cout<<endl;
    }
    return 0;
}


7-2 分香肠

分数 20

作者 neuqAcmClub

单位 东北大学秦皇岛分校

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

输入格式:

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

输出格式:

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

输入样例:

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

2 6

输出样例:

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

4

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB


可以把N段香肠连接成一段,然后分给M个客人说明要切M-1刀,其中有一些刀是和香肠的间隙重合的,所以答案是M-gcd(N,M)

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

int gcd(int a,int b)
{
    while(a!=b)
    {
        if(a>b)a=a-b;
        else b=b-a;
    }
    return a;
}

int main()
{
    int N,M;
    cin>>N>>M;
    int t=gcd(N,M);
    cout<<M-t<<endl;
    return 0;
}


7-3 h0145. 会议安排

分数 20

作者 黄正鹏

单位 贵州工程应用技术学院

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

输入格式:

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

int m,n;

struct H
{
    int b;
    int e;
}h[10010];

bool cmp(H a,H c)
{
    return a.e<c.e;
}

int main()
{
    int temp,sum=0;
    cin>>m;
    for(int i=1;i<=m;i++)
    {
        cin>>n;
        for(int j=1;j<=n;j++)cin>>h[j].b>>h[j].e;
        sort(h+1,h+1+n,cmp);//按照结束时间排序
        temp=h[1].e,sum=1;
        for(int j=2;j<=n;j++)
        {
            if(h[j].b>=temp)temp=h[j].e,sum++;
        }
        cout<<sum;
        if(i!=m)cout<<endl;
    }
    
    return 0;
}


7-4 神秘密码

分数 20

作者 neuqAcmClub

单位 东北大学秦皇岛分校

传说二战时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 begin()
{
    string s,s1;
    int n;
    char x;
    while(cin>>x)
    {
        if(x=='[')
        {
            cin>>n;
            s1=begin();
            while(n--)s+=s1;
        }
        else if(x==']')return s;
        else s+=x;
    }
    return s;
}

int main()
{
    string S=begin();
    cout<<S<<endl;
    return 0;
}


7-5 h0114.国王游戏

分数 20

作者 黄正鹏

单位 贵州工程应用技术学院

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


 比较容易能看出来是一道贪心,问题在于怎么贪。

假设要给两个人排序,两个人左右手分别是 a1,b1   a2,b2  前面所有人左手乘积为S

假设把一号排在二号前面比把二号排在一号前面要更省钱

那么等价于 max( s / b1 , s * a1 /b2 ) < max ( s / b2 , s * a2 / b1 )

已知 s * a1 / b2  > s / b2

所以如果  s * a1 / b2 > s * a2 / b1  那么假设就不成立了

所以有 s * a1 / b2 < s * a2 / b1

即 a1 * b1 < a2 * b2

所以按照左右手乘积从大到小排序即可,这题数据很大,需要用高精度来做,高精部分套模板就行了

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

vector<int> div(vector<int> A, int b)
{
    vector<int> C;
    int r = 0;
    for (int i = A.size() - 1; i >= 0; i -- )
    {
        r = r * 10 + A[i];
        C.push_back(r / b);
        r %= b;
    }
    reverse(C.begin(), C.end());
    while (C.size() > 1 && C.back() == 0) C.pop_back();
    return C;
}

vector <int> mul(vector <int> A,int b)
{
    vector <int> C;
     int t = 0;
    for (int i = 0; i < A.size() || t; i ++ )
    {
        if (i < A.size()) t += A[i] * b;
        C.push_back(t % 10);
        t /= 10;
    }
    
    return C;
}

vector <int> com(vector <int> D,vector <int> E)
{
    if(D.size()>E.size())return D;
    else if(E.size()>D.size())return E;
    else
    {
        for(int i=D.size()-1;i>=0;i--)
        {
            if(D[i]>E[i])return D;
            if(E[i]>D[i])return E;
        }
        return D;
    }
}


struct AC
{
    int l;
    int r;
}ac[1050];

bool cmp(AC a,AC b)
{
    return a.l*a.r<b.l*b.r;
}

int main()
{
    vector <int> B,D,E;
    int n;
    cin>>n;
    for(int i=0;i<=n;i++)cin>>ac[i].l>>ac[i].r;
    E.push_back(ac[0].l);
    B.push_back(ac[0].l);
    sort(ac+1,ac+n+1,cmp);
    for(int i=1;i<=n;i++)
    {
        D=div(B,ac[i].r);
        E=com(D,E);
        B=mul(B,ac[i].l);
    }

    for(int i=E.size()-1;i>=0;i--)cout<<E[i];
    return 0;
}

总结这次周赛,贪心真的好难想啊,感觉是得多练练题,不然第一次见这种形式真的很难推得出来,然后那道递归属实太巧妙了,然后我这种蠢b硬模拟也模拟不出来。。 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Silver_Bullet14

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

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

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

打赏作者

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

抵扣说明:

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

余额充值