第六届华北水利水电大学校赛正式赛(前五题)

目录

1.男孩和女孩

输入格式:

输出格式:

输入样例:

输出样例:

2.原神的大小数

输入格式:

输出格式:

输入样例:

输出样例:

3.第k小整数 

输入格式:

输出格式:

输入样例:

输出样例:

4.抽奖活动

输入格式:

输出格式:

输入样例:

输出样例:

5. 排队买延津火烧

输入格式:

输出格式:

输入样例:

输出样例:


1.男孩和女孩

最近这段时间有很多男孩子使用漂亮女孩子的头像在社交软件上聊天,这让聊天软件上的人区分屏幕对面的人的性别这件事变得很困难。
最近耗子哥在网上和一个使用美女头像的人聊的很开心,但是却不知道对面是男是女。耗子哥很害羞,他不敢问对方要照片或者打视频电话,他只能通过对方的网络昵称来判断对方是男是女,如果昵称中不同字符的数目是奇数,那么对方就是男性,否则是女性,如果对方是男性,那么将不符合耗子哥的心理预期,输出” IGNORE HIM!” ,让耗子哥忽略他,寻找下一个目标,否则输出” CHAT WITH HER!”
同时耗子哥会很高兴,我们希望耗子哥高兴,但是不希望你骗他,所以,如果欺骗耗子哥的感情是不能通过题目的。

输入格式:

一串字符串,字符数目不超过100,代表与耗子哥聊天人的网络昵称,字符仅包含小写字母

输出格式:

如果对方是男生,输出IGNORE HIM!
如果对方是女生,输出CHAT WITH HER!

输入样例:

abc

输出样例:

IGNORE HIM!

 这道题就是简单的统计字符串中不同的字符的个数,例如aabc,其中不同的字符个数是3,并不是2,有部分同学可能会将a忽略掉,直接计算bc,这是错误的;
思路:可以使用stl中的set也可以使用哈希表进行统计不同字符的个数,方法都比较简单;
这里我给出使用set的方法,其他的大家可以自己试试。
 

#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
int main()
{
    string a;
    cin >> a;
    set<char>s(a.begin(),a.end());//将字符串导入s中进行初始化
    int n = s.size();
    if (n % 2 == 0)
    {
        cout << "CHAT WITH HER!" << endl;
    }
    else
        cout << "IGNORE HIM!" << endl;
    return 0;
}

2.原神的大小数

原神是acm的大佬,所以他比较两个数大小的方式也和其他人的方式不太一样。他是通过比较两个十进制数转换成二进制数后,其中1的个数的多少来判断的。比如:5的2进制表示为101,其中有两个1。而8的2进制表示为1000,其中只有一个1,因此我们认定5比8大。但是转换工作太麻烦了。现在他想把这个任务交给聪明的你。

输入格式:

请在这里写输入格式。例如:输入在一行中给出2个不超过1000且大于等于0的整数A和B。

输出格式:

请你输出较大的那个数。(如果大小相同则输出10进制中较大的那个)

输入样例:

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

5 8

输出样例:

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

5

这个题是统计两个2进制数中的1的个数,然后进行比较,大者进行输出,若是1的个数相同,输出10进制数的大者。
代码如下:

#include<iostream>
#include<algorithm>
using namespace std;
int slove(int n)//进行统计1的个数
{
    int count=0;
    while(n)
    {
        if(n%2==1)
        {
            count++;
        }
        n/=2;
    }
    return count;
}
int main()
{
    int a,b;
    cin>>a>>b;
    int len1,len2;
    len1=slove(a);//储存1的个数
    len2=slove(b);//储存2的个数
    if(len1<len2)cout<<b;
    else if(len1>len2)cout<<a;
    else 
        cout<<max(a,b);
    return 0;
}

3.第k小整数 

杨老师想要在现有 n 个正整数(这些正整数均小于 30000,且n≤10000)中,找到第k个最小的整数,k≤1000。数组中不存在相同的正整数。

输入格式:

第一行是全部的 n个正整数和 k数值,第二行开始为 n 个正整数的值,整数间用空格隔开。

输出格式:

输出第 k 个最小整数的值;若无解,则输出“NO RESULT”。

输入样例:

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

10  3
37  6  44  40  52  73  94  82  89  63

输出样例:

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

40

 无需多言,直接上代码:

#include<iostream>
#include<algorithm>
#include<map>
#include<vector>
using namespace std;
int main()
{
    int n,k;
    cin>>n>>k;
    map<int,int>mp;进行统计数是否出现过
    vector<int>ans;
    int t;//临时变量进行储存
    for(int i=0;i<n;i++)
    {
         cin>>t;
         if(mp[t]>=1)//如果t出现过一次,就不进数组中了。
             continue;
         else
         {
             mp[t]++;//出现次数+1
            ans.push_back(t);//将第一次出现的数导入目标数组
         }
    }
    sort(ans.begin(),ans.end());//排序
    if(k>ans.size()||k<0)cout<<"NO RESULT"<<endl;
    else
        cout<<ans[k-1];
    return 0;
}

4.抽奖活动

某公司年会组织了一个抽奖活动,具体要求是这样的:

首先,所有参见活动的人都将一张写有自己名字的字条放入抽奖箱中;

然后,待所有字条加入完毕,每人从箱中取一个字条;

最后,如果取得的字条上写的就是自己的名字,那么恭喜你,中奖了。

请你计算一下,若按这种抽奖方法,没有一个人中奖的概率是多少?

输入格式:

输入数据的第一行是一个整数m,表示测试实例的个数,然后是每行数据,每行包含一个整数n(1<n<=20),表示参加抽奖的人数。

输出格式:

对于每个测试实例,请输出没有一个人中奖的概率(用百分比表示),每个实例输出一行,结果保留两位小数(四舍五入)。

输入样例:

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

3
2
4
6

输出样例:

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

50.00%
37.50%
36.81%

这个概率题在离散数学(第二版)的P100,与此题的舞会拿帽子问题属于同一类,因此我们直接“空手套白狼”,当然这道题答案大家应该都看懂, 直接拿最后结果的通式进行计算。

 

 结果是Dn的通式,(Dn是所有情况的个数),我们这道题求的是概率,所以是Dn/n!所以结果就是中括号里面的一串;
代码如下:

#include<iostream>
#include<algorithm>
using namespace std;
//n的阶乘
int live(int n)
{
    int k = 1;
    for (int i = 1; i <= n; i++)
    {
        k *= i;
    }
    return k;
}
int main()
{
    int n;
    cin >> n;
    while (n--)
    {
        int k;
        cin >> k;
        float res;
        float ret = 0; float t = -1.0;
        for (int i = 1; i <= k; i++)
        {
            ret += t*1.0 / ( live(i));
            t *= -1;
        }
        res = (1 + ret);
        printf("%.2f%%\n", res*100);
    }
    return 0;
}

5. 排队买延津火烧

延津县的大肉火烧很有名,每个从哪里过得游客或者当地人都很喜欢吃,但火烧是现烤的,加工时间有点长,所以火烧店每天都排很长的队。有n个人在排队等着买火烧,假如每个人买的火烧个数是Ti,请编程找出这n个人排队的一种顺序, 使得n个人的平均等待时间最小。(注意:等待自己火烧的加工时间也算等待时间)

输入格式:

输入文件共两行,第一行为n;第二行分别表示第 1 个人到第n个人每人要买的火烧个数(不超过1000)T1,T2,…,Tn,每 个数据之间有 1 个空格。

输出格式:

输出文件有两行,第一行为一种排队顺序,即1到n 的一种排列;第二行为这种排列方案下的平均等待时间(输出结果精确到小数点后两位)。

输入样例:

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

10
56 12 1 99 1000 234 33 55 99 812

输出样例:

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

3 2 7 8 1 4 9 6 10 5
532.00

这道题是经典的贪心,与排队接水的问题别无二致,但是这道题似乎有点问题(个人观点),体重并没有表明买火烧的时间,但是最后让求的是平均等待时间,买火烧的个数的确与时间成正比,但我觉的至少应该得有点提示,所以代码我认为与接水无出其右(尽管过不了这个题),这里我给出两种方法;
代码如下:
1.

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    int n;
    cin>>n;
    int a[n],b[n];
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
        b[i]=a[i];//记录原数组
    }
    sort(a,a+n);//对数组进行排序
    int sum[n];int res=a[0];
    sum[0]=a[0];
    for(int i=1;i<n;i++)
    {
        sum[i]=sum[i-1]+a[i];//计算前缀和
        res+=sum[i];//总等待时间是前缀和的和
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            if(a[i]==b[j])//在原数组中进行比对,找到就打印下标
            {
                if(i==n-1)//最后的下标后面没有空格,直接换行
                {
                    cout<<j+1<<endl;
                    break;
                }
                cout<<j+1<<" ";
                b[j]=0;
                break;
            }
        }
    }
            printf("%.2f",res*1.0/n);
    return 0;
}

2. 
 

#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
using namespace std;
int cmp(pair<int,int>a,pair<int,int>b)
{
    return a.first<b.first;
}
int main()
{
    int n;
    cin>>n;
    vector<pair<int,int>>s(n);//定义数组,将将位置和火烧个数连接起来
    for(int i=0;i<n;i++)
    {
        int x;
        cin>>x;
        s[i]=make_pair(x,i+1);
    }
    sort(s.begin(),s.end(),cmp);//按照火烧的个数进行升序排序
    int sum=s[0].first;
    cout<<s[0].second;
    for(int i=1;i<n;i++)
    {
        s[i].first+=s[i-1].first;//自身直接加上前者,变成前缀和
        sum+=s[i].first;
        cout<<" "<<s[i].second;
    }
    cout<<endl;
    printf("%.2f",sum*1.0/n);
    return 0;
}

这是本次比赛的前5道题,希望能够帮到大家。如有错误,欢迎指正! 

  • 28
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值