HNUCM湖南中医药大学信息科学与工程学院第二届新生赛

 

 

正式赛

 

目录

 

正式赛

问题 A: Yftc的字符串转换

问题 B: XP的午餐

问题 C: XP的电灯

问题 D: XP的宝藏

问题 E: 小小yh的几何

问题 F: 我爱中国

问题 G: 小小yh的数论

问题 H: yangftc的魔法

问题 I: Yangftc&XP的博弈

问题 J: XP的绝对值


 

注意:看不懂C++的学弟学妹,没关系,你把他们转换成C语言的输入输入就可以了,主要也只有输入输出一些地方用了C++的。头文件大多也不用管,很多都是与题目没关系的。清零的函数memset 用的头文件的<string.h> 数学函数<math.h>

 

问题 A: Yftc的字符串转换

题目描述

Ytfc来到了一个魔法密林,里面住着一只魔法兔子,Yftc想去见见这只魔法兔子,但是这个魔法密林很奇怪,你需要将手中的字符串小写变成大写,大写变成小写才能进入。

你能帮帮Yftc完成这个问题嘛?

输入

多组输入,每组一行,包含一个字符串,1<=字符串长度<=200

输出

每行输出一个大小写转换后的字符串。

样例输入 Copy

abcDE
ABCDE

 

样例输出 Copy

ABCde
abcde

 分析:遍历,对每个字符进行操作

//C版
#include <stdio.h>
int main()
{
    char a[1005];//习惯性开大一点
    while (~scanf("%s",a))
    {
        for (int i = 0; a[i] != '\0'; i++)
        {
            if (a[i] >= 'a' && a[i] <= 'z')//小写就转大写
                a[i] -= 32;
            else
                a[i] += 32;
        }
        printf("%s\n",a);
    }
}
//C++
 #include <cstdio>
#include <queue>
#include <sstream>
#include <string>
#include "string.h"
#include <iostream>
#include <math.h>
#include "map"
#include <algorithm>
#include <set>
#include "cctype"
 
#define mst(a, b) memset(a, b, sizeof(a))
const int maxx = 2e5 + 5;
#define ll long long
const ll mod = 1e9 + 7;
const int MAX_N = 1005;
const ll mo = 998244353;
using namespace std;
 
int main()
{
    string a;
    while (cin >> a)
    {
        for (int i = 0; a[i] != '\0'; i++)
        {
            if (a[i] >= 'a' && a[i] <= 'z')
                a[i] -= 32;
            else
                a[i] += 32;
        }
        cout<<a<<endl;
    }
}

 

 

问题 B: XP的午餐

 

题目描述

XP每天都会思考一个问题,今天午餐去哪里吃?这是一个很重要的问题,这会影响到他下午的体力值。他的午餐预算是M元,现在有N种菜品,每一种菜品的价格和能够提供的体力值已知(每种菜品只能选择一次),请问如何选择菜品能够让XP下午的体力值最大呢?

输入

第一行:M元和菜品数量N。
接下来N行,每一行两个整数,分别表示每一种菜品的价格(vi)和能够获得的体力值(wi)。
(0<N<=20,0<=M<=1000)(0<=vi<=50,0<=wi<=100)

输出

最大体力值。

样例输入 

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

样例输出 Copy

14

 

分析:01背包的模板题,具体可以百度01背包问题

#include <cstdio>
#include <queue>
#include <sstream>
#include <string>
#include "string.h"
#include <iostream>
#include <math.h>
#include "map"
#include <algorithm>
#include <set>
#include "cctype"

#define mst(a, b) memset(a, b, sizeof(a))
const int maxx = 2e5 + 5;
#define ll long long
const ll mod = 1e9 + 7;
const int MAX_N = 1005;
const ll mo = 998244353;
const double pi = 3.1415926535898;
using namespace std;
int dp[1005][1005];
int v[1005] = {0};
int w[1005] = {0};

int main()
{

    int m, n;
    while (cin >> m >> n)//等价于while(~scanf("%d%d",&m,&n))
    {
        mst(dp, 0);//多次输入,每次清零。
        mst(w, 0);
        mst(v, 0);

        //v[] 存价格,w[]存体力
        
        for (int i = 1; i <= n; i++)
        {
            cin >> v[i] >> w[i];
        }
        for (int i = 1; i <= n; i++) //菜的数量
        {
            for (int j = 1; j <= m; j++) //价格
            {
                if (j < v[i])
                    dp[i][j] = dp[i - 1][j];
                else
                    dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i]);
            }
        }
        cout << dp[n][m] << endl;
    }
}

 

问题 C: XP的电灯

XP最近发现一个很好玩的问题。现在有N盏电灯,序号为1到N,最开始的时候所有电灯都是关闭的。XP有一群同学,序号是(1~K),这些调皮的同学会去按电灯的开关,每个同学按开关符合一种规律。序号为1的同学会按下序号是1的倍数的灯的开关,序号是2的同学会按下序号是2的倍数的灯的开关(将关的灯打开,开的灯关闭)。现在XP有K位同学,每位同学都去操作一次,问最后有多少盏灯是亮着的?

输入

每行输入两个整数,N,K(K<=N<=1000)

输出

每行输入一个整数,表示打开电灯的数量。

样例输入 Copy

2 2
10 10

样例输出 Copy

1
3

分析:其实可以暴力模拟一波哦,用bool变量存灯泡的状态。 N,K应该都是大于等于1的。1是所有自然数的倍数,则灯泡的初始状态可以设为亮的,从第二个同学开始(true 表示亮)

#include <cstdio>
#include <queue>
#include <sstream>
#include <string>
#include "string.h"
#include <iostream>
#include <math.h>
#include "map"
#include <algorithm>
#include <set>
#include "cctype"

#define mst(a, b) memset(a, b, sizeof(a))
const int maxx = 2e5 + 5;
#define ll long long
const ll mod = 1e9 + 7;
const int MAX_N = 1005;
const ll mo = 998244353;
const double pi = 3.1415926535898;
using namespace std;
bool dp[1005];//存灯的状态

int main()
{
    int n, k;
    while (cin >> n >> k)//等价于while(~scanf("%d%d",&n,&k))
    {
        mst(dp, true);//多组输入,清零

        for (int i = 2; i <= k; i++)//第i个同学
        {
            for (int j = 2; j <= n; j++)第j个编号
                if (j % i == 0)//如果编号j是i同学的倍数灯就改变状态
                {
                    if (dp[j])
                        dp[j] = false;
                    else
                        dp[j] = true;
                }
        }
        int s=0;//s计数
        for(int i=1;i<=n;i++)
        if(dp[i])//如果灯亮,就 s++
        s++;
        cout<<s<<endl;

    }
}

 

问题 D: XP的宝藏

 

题目描述

几经波折和磨难,XP终于拿到了宝库的钥匙和藏宝图,他站在宝库的左上角,这是宝库的入口,出口在右下角。宝库是由一个个小暗格组成的正方形,有些暗格里面有宝藏,也有一些暗格没有。暗格中布满了机关,所有开往左边和上面的门都不能开启,一旦开启就会触发机关,将被万箭穿心。XP开始陷入深深的沉思,他希望活着走出宝库;人总是有贪欲的,他还希望能够带走尽可能多的宝藏,你能否帮到他呢?

输入

每组输入第一个包括一个N,表示N*N的矩阵
第2~n+1行表示该藏宝图 (0<=N<=20)

输出

XP获得的最多宝藏数

样例输入 Copy

3
1 10 2
2 1 1
20 1 1

样例输出 Copy

25

分析:用搜索或者dp都可以的, 

#include <cstdio>
#include <queue>
#include <sstream>
#include <string>
#include "string.h"
#include <iostream>
#include <math.h>
#include "map"
#include <algorithm>
#include <set>
#include "cctype"

#define mst(a, b) memset(a, b, sizeof(a))
const int maxx = 2e5 + 5;
#define ll long long
const ll mod = 1e9 + 7;
const int MAX_N = 1005;
const ll mo = 998244353;
const double pi = 3.1415926535898;
using namespace std;
int ma[30][30] = {0};

int main()
{
    int n;
   while( cin >> n){
       mst(ma,0);//清零
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            cin >> ma[i][j];
    for(int i=1;i<n;i++)
    {
        ma[i][0]+=ma[i-1][0]; // 最上侧和左侧都只能走一个方向
        ma[0][i]+=ma[0][i-1];
    }
    for (int i = 1; i < n; i++)
        for (int j = 1; j < n; j++)
        {
        //ma[i][j]表示从起点,到(i,j)点的最大值。

            ma[i][j]+=max(ma[i][j-1],ma[i-1][j]);//当前值加上它上方和左边中最大那个
        }
        cout<<ma[n-1][n-1]<<endl;
   }
}

 

问题 E: 小小yh的几何

 

题目描述

一个大圆中包含两个小圆,三个圆的圆心均位于同一水平直线。

输入

有多组数据,每行包含两个实数,分别表示两个蓝色圆的面积。s1,s2(1<=s<=100)

输出

绿色部分面积。(保留三位小数)

样例输入 Copy

3.140 3.140

样例输出 Copy

6.280

分析:推公式 可以推出来 S1+S2+S绿 = S大圆   S绿=2π r1r2

#include <cstdio>
#include <queue>
#include <sstream>
#include <string>
#include "string.h"
#include <iostream>
#include <math.h>
#include "map"
#include <algorithm>
#include <set>
#include "cctype"

#define mst(a, b) memset(a, b, sizeof(a))
const int maxx = 2e5 + 5;
#define ll long long
const ll mod = 1e9 + 7;
const int MAX_N = 1005;
const ll mo = 998244353;
const double pi = 3.1415926535898;
using namespace std;

int main()
{
   double r1,r2;
   double s1,s2;
   while(cin>>s1>>s2)
   {
       r1=sqrt(s1/pi);//算出两个小圆的半径
       r2=sqrt(s2/pi);
       printf("%.3f\n",2*pi*r1*r2);
       
   }
}

 

问题 F: 我爱中国

 

题目描述

今年是祖国70周年华诞,LW老师让我用我们专业的方式来在年末的时刻表达一下对祖国的热爱吧!

输出

输出一行“I love China”

样例输出 Copy

I love China

分析:签到题

 

#include <cstdio>
#include <queue>
#include <sstream>
#include <string>
#include "string.h"
#include <iostream>
#include <math.h>
#include "map"
#include <algorithm>
#include <set>
#include "cctype"
 
#define mst(a, b) memset(a, b, sizeof(a))
const int maxx = 2e5 + 5;
#define ll long long
const ll mod = 1e9 + 7;
const int MAX_N = 1005;
const ll mo = 998244353;
using namespace std;
 
int main()
{
    
        cout<<"I love China"<<endl;
     
}
 

 

 

问题 G: 小小yh的数论

 

hyh最近迷上了数论,尤其对费马小定理情有独钟,最近他又发现利用费马小定理能够快速求出2^100除以13的余数

费马小定理定义如下:费马小定理(Fermats little theorem)是数论中的一个重要定理,在1636年提出。如果p是一个质数,而整数a不是p的倍数,则有a^(p-1)≡1(mod p)相信聪明的学弟学妹们一定能够从上面的计算过程中,快速求出p是一个质数且a不是p的倍数的情况下,(a^n)%p的答案

输入

有多组样例,每行包含三个整数a,n,p(2<=a<=9,1<=n<=1000000,2<=p<=14)

输入保证a,p互质。

输出

每组数据输出一个整数,代表(a^n)%p后的值。

样例输入 Copy

2 100 13

样例输出 Copy

3

提示

质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。

9^13=2541865828329超出了int的数据范围

分析:其实按照题意模拟一遍就好了,这里多组输入,索性就它封装成一个函数

#include <cstdio>
#include <queue>
#include <sstream>
#include <string>
#include "string.h"
#include <iostream>
#include <math.h>
#include "map"
#include <algorithm>
#include <set>
#include "cctype"
 
#define mst(a, b) memset(a, b, sizeof(a))
const int maxx = 2e5 + 5;
#define ll long long
const int MAX_N = 1005;
const ll mo = 998244353;
const double pi = 3.1415926535898;
using namespace std;
bool dp[1005];
 
ll fm(ll a, ll b, ll mod)
{
    ll t, y;
    t = 1, y = a;
    while (b != 0)
    {
        if ((b & 1) == 1)
            t = t * y % mod;
        y = y * y % mod;
        b >>= 1; //等价于b/=2;

    }
    return t;
}
int main()
{
 
    int a, n, p;
    while (cin >> a >> n >> p)
 
        cout << fm(a, n, p) << endl;
}
 

 

问题 H: yangftc的魔法

 

题目描述

yangftc会两种魔法,一个是将一个东西变多a份,另一个是将一个东西复制一倍,不过他只有b个单位的能量,每一种魔法都会消耗一单位的能量,yangftc现在有x个单位的钱,yangftc想让他的钱尽量多,你能告诉他他最多能有多少钱吗

输入

首先输入t代表样例数量

后跟t组样例每一个样例一行

每个样例输入三个数字a,b,x

输出

yangftc最多能拥有的钱数

数据范围  1<=t<=500  1<=a<=40  1<=b<=40  1<=x<=10

样例输入 Copy

1
1 2 1

样例输出 Copy

4

分析:思考一下就知道在x小于a之前,选择加a比x翻倍划算。于是模拟一波

#define mst(a, b) memset(a, b, sizeof(a))
const int maxx = 2e5 + 5;
#define ll long long
const ll mod = 1e9 + 7;
const int MAX_N = 1005;
const ll mo = 998244353;
const double pi = 3.1415926535898;
using namespace std;
int dp[1005][1005];
int v[1005] = {0};
int w[1005] = {0};
 
int main()
{
 
    ll t;
    cin >> t;
    ll a, b, x;
 
    while (t--)
    {
        cin >> a >> b >> x;
        while (b--)//当还有能量时
        {
            if (x < a)
                x += a;
            else
            {
                x *= 2;
            }
 
        }
        cout<<x<<endl;
    }
}

问题 I: Yangftc&XP的博弈

题目描述

yangftc逃出魔法大陆后,发现自己在一片沙漠,旁边是XP,他是从另一个魔法大陆来的,而附近只有一瓶水,这只够一个人走出去,为了存活下来他们决定玩一个游戏来决定水的归属

他们找来一些石子(不用管他们怎么找过来的)放在一起变成一堆。如果这一堆石子个数为奇数则可以拿去一个或者两个石子,如果这一堆石子个数为偶数则只能拿去一个石子,两个人轮流进行操作,yangftc先手,取走最后一个石子的人胜,假设两个人都知道游戏的诀窍,判断yangftc是否能赢

输入

第一个数字t代表样例数量

后面t个样例,每一个样例输入一个整数n代表石子的个数

输出

yangftc能赢输出YES,否则输出NO

数据范围 1<=t<=500   1<=n<=100000

样例输入 Copy

2
2
3

样例输出 Copy

NO
YES

分析:多做几次就会发现规律。n为奇数yftc就会赢,否则就会输。

因为两个人都足够聪明,  我们知道 n = 1的时候 先手必赢,n = 2 的时候必输,那么 n = 3的时候可以丢一个或2个 那么丢完之后就是 剩下1 个或者2个。就相当于 后手在 初始状态下为 n 为1或者 2的先手。 n=4,5,6...后面的结果就可以从前面的值推出来。 

#include <cstdio>
#include <queue>
#include <sstream>
#include <string>
#include "string.h"
#include <iostream>
#include <math.h>
#include "map"
#include <algorithm>
#include <set>
#include "cctype"
 
#define mst(a, b) memset(a, b, sizeof(a))
const int maxx = 2e5 + 5;
#define ll long long
const ll mod = 1e9 + 7;
const int MAX_N = 1005;
const ll mo = 998244353;
using namespace std;
 
int main()
{
     int t; 
     cin>>t;
     while(t--)
     {
         int data ;
         cin>>data;
         if(data%2)
         cout<<"YES\n";
         else
         cout<<"NO\n";
     }
}

问题 J: XP的绝对值

题目描述

XP今天要教他的初一妹妹绝对值,但是XP觉得这个太简单了,不想教她。于是XP想写一个程序,让妹妹手动输入,可以得出来答案。

输入

包含多组输入,每行一个值n。

输出

对于每组输入,你只需输出一行,每行一个值,表示n的绝对值。

样例输入 Copy

1
0
-1

样例输出 Copy

1
0
1

分析:签到题,库函数的使用

#include <cstdio>
#include <queue>
#include <sstream>
#include <string>
#include "string.h"
#include <iostream>
#include <math.h>
#include "map"
#include <algorithm>
#include <set>
#include "cctype"
 
#define mst(a, b) memset(a, b, sizeof(a))
const int maxx = 2e5 + 5;
#define ll long long
const ll mod = 1e9 + 7;
const int MAX_N = 1005;
const ll mo = 998244353;
using namespace std;
 
 
int main()
{
  int n;
  while(cin>>n)
  cout<<abs(n)<<endl;
}
 

 

 

 

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我可以为您讲解一下 HNUCM 最小生成树(Prim)的算法过程。 首先,Prim 算法是一种贪心算法,用于求解带权无向连通图的最小生成树。下面是具体的算法过程: 1. 选取任意一个顶点作为起点,将其加入到生成树中。 2. 找到与已经加入到生成树中的顶点相邻的所有顶点,并计算它们与生成树的距离。 3. 从这些顶点中选取距离最小的顶点,将其加入到生成树中。 4. 重复步骤2和3,直到生成树中包含了所有的顶点。 在具体实现时,可以使用一个数组来记录每个顶点是否已经加入到生成树中,以及另一个数组来记录每个顶点与生成树的距离。每次选择距离最小的顶点时,可以使用一个最小堆来优化。 至于 HNUCM 最小生成树 Prim 算法的具体实现,可以参考以下代码: ```python import heapq def prim(graph): n = len(graph) visited = [False] * n distance = [float('inf')] * n distance[0] = 0 heap = [(0, 0)] result = 0 while heap: (d, u) = heapq.heappop(heap) if visited[u]: continue visited[u] = True result += d for v, weight in graph[u]: if not visited[v] and weight < distance[v]: distance[v] = weight heapq.heappush(heap, (weight, v)) return result ``` 这段代码实现了 HNUCM 最小生成树 Prim 算法的过程,其中 graph 是一个邻接表表示的带权无向连通图,每个元素是一个二元组 (v, w),表示从节点 u 到节点 v 有一条边权为 w 的边。算法的返回值是最小生成树的总权值。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

°PJ想做前端攻城狮

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

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

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

打赏作者

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

抵扣说明:

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

余额充值