我是靠谱客的博主 高大含羞草,最近开发中收集的这篇文章主要介绍2017第一届河北省大学生程序设计竞赛题解超级密码考研声之形春游秋游自动签到机奇妙糖果屋商品清算奇异旅馆,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

超级密码

小明今年9岁了,最近迷上了设计密码!今天,他又设计了一套他认为很复杂的密码,并且称之为“超级密码”. 说实话,这套所谓的“超级密码”其实并不难:对于一个给定的字符串,你只要提取其中的数字,然后连在一起构成一个整数,再乘以小明的幸运数字513,就是解密后的结果了~比如,字符串“ads2d4,122”,提取后的整数是24122,然后乘以513,就能得到解密后的结果:12374586.注:题目保证解密后的结果在32位无符号整数范围.

输入描述

输入首先包括一个正整数N,表示有N组测试用例. 每组数据占一行,包含一个长度不超过30的字符串.

输出描述

请根据题目要求输出解密后的结果,每组数据输出一行.

样例输入

2
ads2d4,122
0023asdf2AA90

样例输出

12374586
11947770

思路:提取每一位数字,新答案为旧答案*10+本位数字即可,注意数字范围。

code:

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

char ch[100];

int main()
{
    int n;
    cin >> n;

    while(n--)
    {
        long long cnt = 0;
        scanf("%s", ch);
        
        int len = strlen(ch);
        for(int i = 0; i < len; ++i)
            if(ch[i] >= '0' && ch[i] <= '9')
                cnt = cnt * 10 + (ch[i] - '0');
        printf("%lldn", cnt*513);
    }
    return 0;
}


考研

题目描述

今天参加比赛的同学,我想以后准备考研的一定有不少.以河北某高校为例, 一共要考4门,分别是:数学(满分150)、英语(满分100)、政治(满分100)、专业课(满分150). 不过,你知道考研分数线的这个特点吗——不仅总分要过分数线,单科也必须过线! 假设某年度该校研究生录取的分数线是这样的:数学和专业课单科分数线是85(含), 英语和政治单科分数线是55(含),总分分数线是305(含).并且规定——在单科和总分均过线的前提下, 总分370分(含)以上的是公费生,否则是自费生.现在告诉你一些考生的分数,你能判断他们的录取情况吗?

输入描述   

输入数据第一行是一个正整数C(C<=100),表示有C组测试用例.
   接下来C行,每行4个整数,分别表示一位考生的数学、英语、政治和专业课成绩.

输出描述   

输入数据第一行是一个正整数C(C<=100),表示有C组测试用例
接下来C行,每行4个整数,分别表示一位考生的数学、英语、政治和专业课成绩.

样例输入

3
100 80 85 120
90 60 65 110
140 50 75 135

样例输出

A
B
C

思路:直接分类即可。

code:

#include<stdio.h>
int main()
{
	int n;
	scanf("%d",&n);
	while(n--)
	{
		int a,b,c,d,sum;
		scanf("%d%d%d%d",&a,&b,&c,&d);
		sum=a+b+c+d;
		if((sum>=370)&&(a>=85)&&(b>=55)&&(c>=55)&&(d>=85))
			printf("An");
		else if((sum>=305)&&(a>=85)&&(b>=55)&&(c>=55)&&(d>=85))
			printf("Bn");
		else 
                        printf("Cn");
	}
	return 0;
}


声之形

题目描述

为了决定去哪个影院看《声之形》,小S和小T决定抛一次公平的1元硬币决定最终去哪儿.在以前,他们为了决定去哪个电影院已经抛掷了若干次,其中有a次正面向上和b次反面向上.而且约定了如果正面向上就是小S赢,否则是小T赢.现在告诉你他们以前抛掷的结果,请告诉小S,这次为了看《声之形》,他如愿去自己想去的电影院的概率是多少.

输入描述

输入数据第一行是一个正整数T,保证有T组测试数据,保证.T<=1e3 接下来一共T行,每行有两个正整数a,b,保证1<=a,b<=2^{60}.保证小S和小T想去的电影院不一致且抛掷结果只会出现正面向上或者反面向上.

输出描述

输出一行,表示小S赢的概率,精确到小数点后12位有效数字,你的答案必须和参考答案完全一致才算正确. 每次答案输出一行.

样例输入

1
999 999

样例输出

0.500000000000

思路:概率肯定为0.5,和之前没关系。

code:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    int a, b; 
    cin >> n;

    while(n--)
    {
        scanf("%d%d", &a, &b);
        printf("0.500000000000n");
    }
    return 0;
}


春游

题目描述

春天来了 大地万物复苏 一切都是生机勃勃 门前的这簇绿 和远处的那一抹红 都充满了诗意 是的 春天就是这样 给人无限的希望 经过了连续多天紧张的训练,教练决定组织ACM集训队的N位同学一起去郊外感受春天的气息. 为了方便郊游,活动地点提供了 B(≥N) 辆自行车供人租用,现在已知第 i位同学自己携带了元,租用第 j 辆自行车的价格为元. 就在大家忙着租车的时候,教练突然提出了一个问题考大家:在允许同学们相互借钱的前提下,你能计算出最多有多少位同学能够成功租车吗?

输入描述

输入数据第一行是一个正整数T,表示有T组测试数据. 每组数据的第一行包括2个正整数N和B,分别表示学生人数和自行车数量. 每组数据的第二行包含N个正整数Mi,表示N位同学每人携带了Mi元. 每组数据的第三行包含B个正整数Cj,表示B辆自行车每辆车的租费. [数据范围] 1 <= T <= 100 1 <=n<=100, n <= B <= 100 1 <= M[i] <= 1000, 1 <= c[i] <= 1000

输出描述

请输出能够成功租车的最多人数,每组数据输出一行

样例输入

1
4 5
2 1 9 6
3 5 4 7 6

样例输出

4

思路:贪心,把钱集中到一起,优先买小的即可。因为对于当前最便宜的物品,不买肯定亏。

code:

#include<bits/stdc++.h>
using namespace std;
int brr[105];
long long cnt = 0;

int main(){
    int t;
    int a, b, c;
    cin >> t;

    while(t--)
    {
        cnt = 0;//钱数
        scanf("%d%d", &a, &b);
        for(int i = 0; i < a; ++i){
            scanf("%d", &c);
            cnt += c;
        }

        for(int j = 0; j < b; ++j)
            scanf("%d", &brr[j]);

        sort(brr, brr + b);//优先便宜的

        int tag = 0;
        for(int i = 0; i < b; ++i){
            if(cnt < brr[i]) break;//钱不够
            cnt -= brr[i];
            tag++;
        }
        if(tag > a)
            printf("%dn", a);
        else
            printf("%dn", tag);
    }
    return 0;
}


秋游

题目描述

秋天来了 不必为几片落叶流泪 也不必为秋风 而轻言感伤 享受秋天吧 享受那秋日阳光 享受菊花黄 享受桂花香 经过了连续多天紧张的第二阶段训练,教练又决定组织ACM集训队的N位同学一起去郊游. 为了方便郊游,活动地点提供了 B(≥N) 辆自行车供人租用,现在已知第 i位同学自己携带了 Mi 元,租用第 j 辆自行车的价格为 Cj 元. 就在大家忙着租车的时候,丁爸突然提出了一个问题考大家:假如规定每位同学只能用自己携带的钱租自行车(即:不允许借别人的钱),并且只允许为自己租车,你能计算出最多有多少位同学能够成功租车吗?

输入描述

输入数据第一行是一个正整数T,表示有T组测试数据. 每组数据的第一行包括2个正整数N和B,分别表示学生人数和自行车数量. 每组数据的第二行包含N个正整数Mi,表示N位同学每人携带了Mi元. 每组数据的第三行包含B个正整数Cj,表示B辆自行车每辆车的租费. [数据范围] 1 <= T <= 100 1 <=n<=100, n <= B <= 100 1 <= m[i] <= 10001 <= c[i] <= 1000

输出描述

请输出能够成功租车的最多人数,每组数据输出一行.

样例输入

1
4 5
2 1 9 6
3 5 4 7 6

样例输出

2

思路:和春游的区别就是不能借钱。贪心思路:人和物都升序排序。对于钱最少的人来说,如果能买得起最便宜的物品,就买。买不起,就跳过这个人。

原因如下:

1)这个人买不起最便宜的,肯定也买不起后面的,所以直接放弃这个人。

2)这个人可以买最便宜的,是否让他买一个更贵的呢?(看起来这样更赚)

不是的,白扯。

比如它买第n个,那么它后面的n-1个人一定可以买前n-1个车,因为那些人>这个人>那些车

所以老老实实的买最便宜的。

code:

#include<bits/stdc++.h>
using namespace std;
int arr[105];
int brr[105];
long long cnt = 0;
int main(){
    int t;
    int a, b, c;
    cin >> t;
    while(t--){
        scanf("%d%d", &a, &b);
        for(int i = 0; i < a; ++i)
            scanf("%d", &arr[i]);
        sort(arr, arr + a);
        for(int j = 0; j < b; ++j)
            scanf("%d", &brr[j]);
        sort(brr, brr + b);

        int tag = 0;
        int index1 = 0, index2 = 0;//人,车的下标
        while(index1 < a && index2 < b)
        {
            if(arr[index1] >= brr[index2])
            {
                index1++;
                index2++;
                tag++;
            } 
            else 
                index1++;
        }
        printf("%dn", tag);
    }
    return 0;
}


自动签到机

题目描述

  今天是报到日,在排了一下午的队之后,终于轮到了查尔明签到。

这里使用了一种叫做“自动签到机”的高科技,在签到时,选手需要输入验证码来进行确认。这个系统每次会给出T张10*10的黑白图片,每张的黑色部分形成了“0”、“1”、“8”三个数字中的一种,而且出于人性化设计,它不会让用户眼花,不会把数字写得不规范,也不会在一张图片中放入两个以上的数字,更不会去帮用户治疗多年的颈椎病.可是就算这样,查尔明还是不想去识别,因为他曾经写过能自动识别验证码的程序.不幸的是,当查尔明打开笔记本的时候,却怎么也找不到那个程序了. 亲爱的同学,你能帮助查尔明完成签到吗?

输入描述

输入文件第一行包含一个正整数T(T≤15),表示图片的张数. 接下来T个部分,每个部分是一个10*10的矩阵(不含空格),其中“_”表示白色,“#”表示黑色.

输出描述

输出文件包含T行,每行一个整数,其中第i行输出第i张图片上的数字.

样例输入

1
_____#____
____##____
___#_#____
__#__#____
_____#____
_____#____
_____#____
_____#____
__#######_
__________

样例输出

1

思路:

判断0,1,8,观察可知,1没有封闭区域,0有一个封闭区域,8有两个封闭区域。

搜索有几个区域即可。(不会的看经典例题:八连通)

注意:

数字可能顶住边界造成假的分割,所以记得在外面加圈。

code:

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

int G[15][15];     //0 :_      1: #
int cnt = 0;
int dir[4][2] = {0, -1, 0, 1, 1, 0, -1, 0};

struct Node{int x, y;};

bool check(int x, int y)
{
    if(x >= 0 && x < 12 && y >= 0 && y < 12 && G[x][y] == 0) return true;
    return false;
}

void Init(){
    int c;
    cnt = 0;
    memset(G, 0, sizeof G);
    for(int i = 1; i <= 10; ++i){
        getchar();
        for(int j = 1; j <= 10; ++j){
            scanf("%c", &c);
            if(c == '#')
                G[i][j] = 1;
        }
    }
}

void bfs(int x, int y){
    cnt++;
    Node node = {x, y};
    queue<Node> q;
    q.push(node);
    G[x][y] = 1;

    while(q.size()){
        Node tmp = q.front();
        q.pop();
        int tx = tmp.x;
        int ty = tmp.y;

        for(int i = 0; i < 4; ++i){
            int dx = tx + dir[i][0];
            int dy = ty + dir[i][1];

            if(check(dx, dy)){
                Node dnode = {dx, dy};
                q.push(dnode);
                G[dx][dy] = 1;
            }
        }
    }
}

int main(){
   int t;
   cin >> t;

   while(t--){
       Init();
       for(int i = 0; i < 12; ++i)
           for(int j = 0; j < 12; ++j)
               if(G[i][j] == 0)
                   bfs(i, j);

       if(cnt == 1)
           printf("1n");
       else if(cnt == 2)
           printf("0n");
       else if (cnt == 3)
           printf("8n");
   }

    return 0;
}


奇妙糖果屋

题目描述

奇异王国里有很多奇怪的事物.比如奇怪的人(每个人都拥有一个智慧值),奇怪的商店… 这不,奇异糖果屋今天开业了,老板在门口拉上了“糖果送送送”的横幅来吸引顾客. 糖果的具体赠送方案为对于一个智慧值为x的人来说,他所能获得的糖果数量f(x)满足如下条件:

  1. f(0) = 0,
  2. f(2x) = f(x),
  3. f(2x+1) = f(2x) + 1, 整天搞怪的小A带着朋友们闻讯而来,他想出了一个游戏,游戏的规则是这样的:每个人根据自己的智慧值拿到糖果后互相比较开心值,开心值最大的人即为胜者. 开心值的定义为除了自己以外其他所有人获得糖果数量的异或值. 但是小A只负责搞怪,目前已知每个人的智力值,聪明的你能否帮助他提前知道谁能获胜以及这个人的开心值为多少呢? 每个人按照给定顺序从1开始编号.如果有多个人的开心值相等,则编号最小的获胜.

输入描述

输入数据的第一行是一个整数T,表示测试实例的个数,保证T<=100. 每组输入数据占两行. 第一行为一个整数n,代表去糖果屋的人数。(1<=n<= 10 5) 第二行为n个整数,代表每个人的智力值 (1<=ai <=10 9 ) 题目保证n>=50000的数据组数不超过10组.

输出描述

每组数据输出两个整数,依次表示获胜的人的编号以及他所获得的开心值,中间用空格隔开.每组一行.

样例输入

1 
2
3 4

样例输出

2 2

思路:观察发现,f(x)是x的二进制中1的个数。(很简单,是奇数就+1,偶数不加,一下就看出来了啊。。。)

算出异或总和tag。异或性质:a ^ b ^ b=a ,对于每个人我们用他的糖果数异或tag即可。

为了要求的顺序:自定义排序

code:

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

const int maxn = 100000 + 5;
int arr[maxn];
struct Node{
    int v;
    int id;
    //按规则自定义排序
    bool operator < (const Node& node) const{
        if(v != node.v){
            return v > node.v;
        } else {
            return id < node.id;
        }
    }
};

Node nodes[maxn];

int fun(unsigned int x)//1的个数
{
    int cnt = 0;
    while(x != 0)
    {
        if(x & 1)cnt++;
        x >>= 1;
    }

    return cnt;
}

int main(){

    int t;
    int n, a;
    cin >> t;

    while(t--){
        scanf("%d", &n);
        for(int i = 0; i < n; ++i){
            scanf("%d", &a);
            arr[i] = fun(a);
        }

        int tag = arr[0];//算总和
        for(int i = 1; i < n; ++i){
            tag ^= arr[i];
        }

        for(int i = 0; i < n; ++i)
        {//处理数据
            arr[i] = tag^arr[i];
            nodes[i].v = arr[i];
            nodes[i].id = i+1;
        }

        sort(nodes, nodes + n);

        printf("%d %dn", nodes[0].id, nodes[0].v);
    }    
    return 0;
}


商品清算

题目描述

查尔明和迈克是好朋友. 每天早晨,查尔明都会去超市购物. 迈克有着敏锐的观察力,很快就发现了一个有趣的现象:每天查尔明选购的商品的总价格都是奇数! 商店里共有n种商品,其中第i种商品的价格为v[i].对于每种商品,查尔明每天最多只会购买一件. 每天下午,查尔明都会清算今天花了多少钱,但是他买的东西实在是太多了,他记不清自己到底买了哪些东西,只记得这一天他买了k件商品.于是他只好向口算能力超强的迈克求助,希望他能算出自己最多可能花了多少钱. 迈克的口算只能应付10以内的n和k,所以他把这个任务交给了你.当然,查尔明也有可能记错k,所以如果不存在任何一种方案,请输出-1.

输入描述

输入文件的第一行包含两个正整数n(n<=100000),m(m<=100000),分别表示商品种数和询问的个数. 第二行包含n个正整数,依次表示每种商品的价格. 接下来m行每行包含一个整数k,依次表示每个询问. 对于100%的数据,保证1<=v[i]<=100,000,0<=k<=n.

输出描述

输出文件包含m行,每行一个整数,如果有解输出总价格的最大值,否则输出-1.保证测试总组数为1组。

样例输入

4 3
4 2 1 3
2
3
4

样例输出

7
9
-1
思路:k个数凑最大奇数,据说有简单方法,我想的是dp,
思考:
偶数=奇数+奇数,或者偶数+偶数
奇数=奇数+偶数,或者偶数+奇数

设dp[i]为i个数凑最大奇数是多少,思考有哪些情况?

1)i-1个数凑出一个最大的奇数,加上没选的最大偶数。

2)i-1个数凑出一个最大的偶数,加上没选的最大奇数。

那很显然的想到我们要再求一个值,i个数凑最大偶数是多少?

1)i-1个数凑出一个最大的奇数,加上没选的最大奇数

2)i-1个数凑出一个最大的偶数,加上没选的最大偶数

很自然的,我们想到把奇数偶数分开存放并且降序排序。并且dp的值不是简单的一个数,还要记录做出选择时,奇数偶数的下标是多少,这样方便我们确定当前未选中的最大奇数和最大偶数是多少。

code:

解释一下dp含义:

dp[i][0][0]:i个数凑最大奇数的值

dp[i][0][1]:当前情况的奇数下标

dp[i][0][2]:当前情况的偶数下标

 

dp[i][1][0]:i个数凑最大偶数的值

dp[i][1][1]:当前情况的奇数下标

dp[i][1][2]:当前情况的偶数下标

注意longlong

#include <bits/stdc++.h>
#include <cstdio>
using namespace std;
long long arr[100005];
long long brr[100005];
long long dp[100005][2][3];
int main(void)
{
    int a,b;
    long long c;
    scanf("%d%d",&a,&b);
    int x=0;
    int y=0;
    int ans=a;
    //分别存放并排序
    while(a--)
    {
        scanf("%lld",&c);
        if(c%2==0)brr[y++]=c;
        else arr[x++]=c;
    }
    sort(arr,arr+x,greater<int>());
    sort(brr,brr+y,greater<int>());
    
    //瞎初始化了一波
    dp[0][0][0]=arr[0];
    dp[0][0][1]=0;
    dp[0][0][2]=-1;
    dp[0][1][0]=brr[0];
    dp[0][1][1]=-1;
    dp[0][1][2]=0;
    if(x==0)dp[0][0][0]=-1;
    if(y==0)dp[0][1][0]=-1;
    
    for(int i=1;i<ans;i++)
    {
        dp[i][0][0]=-1;
        dp[i][1][0]=-1;
        if(dp[i-1][0][0]>=0)//前奇
        {
            //奇+偶
            if(dp[i-1][0][2]<y-1)
            {
                dp[i][0][0]=dp[i-1][0][0]+brr[dp[i-1][0][2]+1];
                dp[i][0][1]=dp[i-1][0][1];
                dp[i][0][2]=dp[i-1][0][2]+1;
            }
            //奇+奇
            if(dp[i-1][0][1]<x-1)
            {
                dp[i][1][0]=dp[i-1][0][0]+arr[dp[i-1][0][1]+1];
                dp[i][1][1]=dp[i-1][0][1]+1;
                dp[i][1][2]=dp[i-1][0][2];
            }
        }
        if(dp[i-1][1][0]>=0 && dp[i-1][1][0]+arr[dp[i-1][1][1]+1]>dp[i][0][0] && dp[i-1][1][1]<x-1)
        {
            //偶+奇>奇+偶
            dp[i][0][0]=dp[i-1][1][0]+arr[dp[i-1][1][1]+1];
            dp[i][0][1]=dp[i-1][1][1]+1;
            dp[i][0][2]=dp[i-1][1][2];
        }
        if(dp[i-1][1][0]>=0 && dp[i-1][1][0]+brr[dp[i-1][1][2]+1]>dp[i][1][0] && dp[i-1][1][2]<y-1)
        {
            //偶+偶>奇+奇
            dp[i][1][0]=dp[i-1][1][0]+brr[dp[i-1][1][2]+1];
            dp[i][1][1]=dp[i-1][1][1];
            dp[i][1][2]=dp[i-1][1][2]+1;
        }
    }
    for(int i=0;i<b;i++)
    {
        int kk;
        scanf("%d",&kk);
        if(kk>0)
          printf("%lldn",dp[kk-1][0][0]);
        else 
          printf("-1n");
    }
}


奇异旅馆

题目描述

玩了一天,小A又带着他的小伙伴们来到了当地的奇异旅馆. 这个旅馆共有n层,每层分别有ai个床位.由于没有电梯,大家都希望尽可能住在较低的楼层. 现在小A提出了q个操作,操作分为两种:

  1. 从第x层开始向上安置num个小伙伴住宿.
  2. 询问前k层一共已经安置的小伙伴数目. 假设一开始每层楼的床位都是未被使用的,且若操作1中x层及以上的房间无法容纳所要安置的人,则尽可能多地安置,剩余部分忽略.

输入描述

输入数据的第一行是一个整数T,表示测试实例的个数,保证T<=30. 对于每组测试样例,第一行给出n和q.(1<=n<=100000,1<=q<= 100000) 接下来一行共有n个整数 .(1<=ai<=1e9) 接下来共有q行,每行表示一个操作. 第一种操作的给出形式为:1 x num.(1<=x<=n,1<= num<=1e9) 第二种操作的给出形式为:2 k.(1<= k<=n) 题目保证n>=50000且q>=50000的数据组数不超过5组.

输出描述

每组样例中,对于第一种操作,若x层及以上的房间无法容纳所要安置的人,输出“overflow”. 对于第二种操作,输出所询问的值. 每个输出数据占一行,且每组数据后输出一个空行.

样例输入

1
3 5
2 3 5
1 1 4
2 2
1 2 3
2 2
1 3 10

样例输出

4
5
overflow

暴力肯定gg,但是也没有多么花里胡哨,就是挺裸的题,具体看代码。

code:

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

const int maxn = 100000 + 5;
long long crr[maxn];
long long num[maxn];

//获取x最低位1
int lowbit(int x){
    return x&(-x);
}

//单点更新:位置x更新为y
void update(int x, long long y, int n){
    for(int i = x; i <= n; i+=lowbit(i))
        crr[i] += y;
}

//区间查询1-x
long long getsum(int x){
    long long ans = 0;
    for(int i = x; i > 0; i-=lowbit(i))
        ans += crr[i];
    return ans;
}

int main(){
    int T;
    cin >> T;

    while(T--){
        memset(crr, 0, sizeof(crr));
        int n, m;
        int a, b;
        long long c;
        scanf("%d%d", &n, &m);
        //输入每个房间的床数
        for(int i = 1; i <= n; ++i)
            scanf("%d", &num[i]);

        for(int i = 0; i < m; ++i)
        {
            scanf("%d", &a);
            if(a == 1)
            {
                scanf("%d%lld", &b, &c);
                int j;
                for(j = b; j <= n; ++j)
                {
                    if(c >= num[j] && num[j] > 0)
                    {
                        update(j, num[j], n);
                        c -= num[j];
                        num[j] = 0;
                    }
                    if(c == 0)
                        break;
                    else if (c < num[j])
                    {
                        update(j, c, n);
                        num[j] -= c;
                        c = 0;
                        break;
                    }
                }

                if(j == n+1 && c > 0){
                    printf("overflown");
                }
            }
            else 
            {
                scanf("%d", &b);
                printf("%lldn", getsum(b));
            }
        }
        cout << endl;
    }
    return 0;
}

 

 

还有硬核题,本渣不会做了。

最后

以上就是高大含羞草为你收集整理的2017第一届河北省大学生程序设计竞赛题解超级密码考研声之形春游秋游自动签到机奇妙糖果屋商品清算奇异旅馆的全部内容,希望文章能够帮你解决2017第一届河北省大学生程序设计竞赛题解超级密码考研声之形春游秋游自动签到机奇妙糖果屋商品清算奇异旅馆所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(42)

评论列表共有 0 条评论

立即
投稿
返回
顶部