初见蓝桥杯

由于我怕我太菜所以大一没报蓝桥杯比赛(我这个人很自卑呜呜呜)

P8637 [蓝桥杯 2016 省 B] 交换瓶子

题目描述

有 N 个瓶子,编号 1N,放在架子上。

比如有 55 个瓶子:

2,1,3,5,4

要求每次拿起 22 个瓶子,交换它们的位置。

经过若干次后,使得瓶子的序号为:

1,2,3,4,5

对于这么简单的情况,显然,至少需要交换 22 次就可以复位。

如果瓶子更多呢?你可以通过编程来解决。

输入格式

第一行:一个正整数 N(1<N<10000),表示瓶子的数目。

第二行:N 个正整数,用空格分开,表示瓶子目前的排列情况。

输出格式

输出数据为一行一个正整数,表示至少交换多少次,才能完成排序。

输入输出样例

输入 #1
5
3 1 2 5 4
输出 #1
3
输入 #2
5
5 4 3 2 1
输出 #2
2
复制代码
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,m,p[1000010],x[1000010],y[1000010];
 4 int find(int x)
 5 {
 6     if(x!=p[x]) p[x]=find(p[x]);
 7     return p[x];
 8 }
 9 int main()
10 {
11     cin>>n>>m;
12     for(int i=1;i<=n;i++) p[i]=i;
13     while(m--)
14     {
15         int a,b,c;
16         cin>>c>>a>>b;
17         if(c==1)
18             p[find(a)]=find(b);
19         else
20         {
21             if(find(a)==find(b)) cout<<'Y'<<endl;
22             else cout<<'N'<<endl;
23         }
24     }
25     return 0;
26 }
复制代码

题目描述

2020 年春节期间,有一个特殊的日期引起了大家的注意:2020 年 2 月 2 日。因为如果将这个日期按 yyyymmdd 的格式写成一个 88 位数是 20200202,恰好是一个回文数。我们称这样的日期是回文日期。

有人表示 20200202 是“千年一遇” 的特殊日子。对此小明很不认同,因为不到 2 年之后就是下一个回文日期:20211202 即 2021 年 12 月 2 日。

也有人表示 20200202 并不仅仅是一个回文日期,还是一个 ABABBABA 型的回文日期。对此小明也不认同,因为大约 100100 年后就能遇到下一个 ABABBABA 型的回文日期:21211212 即 2121 年12 月12 日。算不上“千年一遇”,顶多算“千年两遇”。

给定一个 8 位数的日期,请你计算该日期之后下一个回文日期和下一个 ABABBABA 型的回文日期各是哪一天。

输入格式

输入包含一个八位整数 N,表示日期。

输出格式

输出两行,每行 11 个八位数。第一行表示下一个回文日期,第二行表示下 一个 ABABBABA 型的回文日期。

输入输出样例

输入 #1
20200202
输出 #1
20211202
21211212
复制代码
#include<bits/stdc++.h>
using namespace std;
bool f1,f2;
int res;
int p[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
bool check(int a,int b,int c,int d)
{
    //dcba
    if(d*10+c<=12&&d*10+c>0)
    {
        if(p[d*10+c]>=b*10+a&&b*10+a>0) return true;
        else return false;
    }
    else return false;
}
bool checkab(int a,int b,int c,int d)
{
    if(d*10+c<=12&&d*10+c>0)
    {
        int x=d*10+c;
        if(p[x]>=b*10+a&&((a*10+b)==(c*10+d))&&b*10+a>0) return true;
        else return false;
    }
    else return false;
}
int main()
{
    string s;
    cin>>s;
    for(int a=1;a<=9;a++)
    {
        if(f1&&f2) break;
        for(int b=0;b<=9;b++)
        {
            if(f1&&f2) break;
            for(int c=0;c<=9;c++)
            {
                if(f1&&f2) break;
                for(int d=0;d<=9;d++)
                {
                    if(f1&&f2) break;
                    for(int e=0;e<=9;e++)
                    {
                        if(f1&&f2) break;
                        for(int f=0;f<=9;f++)
                        {
                            if(f1&&f2) break;
                            for(int g=0;g<=9;g++)
                            {
                                if(f1&&f2) break;
                                for(int h=0;h<=9;h++)
                                {
                                    if(a==s[0]-'0'&&b==s[1]-'0'&&c==s[2]-'0'&&d==s[3]-'0'&&e==s[4]-'0'&&f==s[5]-'0'&&g==s[6]-'0'&&h==s[7]-'0')
                                        res++;
                                    if(res==1&&check(a,b,c,d)&&!f1)
                                    {
                                        cout<<a<<b<<c<<d<<d<<c<<b<<a<<endl;
                                        f1=true;
                                    }
                                    if(res==1&&checkab(a,b,c,d)&&!f2)
                                    {
                                        cout<<a<<b<<c<<d<<b<<a<<d<<c<<endl;
                                        f2=true;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return 0;
}
复制代码

P8623 [蓝桥杯 2015 省 B] 移动距离

X 星球居民小区的楼房全是一样的,并且按矩阵样式排列。其楼房的编号为 1,2,3,⋯1,2,3,⋯ 。

当排满一行时,从下一行相邻的楼往反方向排号。

比如:当小区排号宽度为 66 时,开始情形如下:

1  2  3  4  5  6
12 11 10 9  8  7

13 14 15 ....

我们的问题是:已知了两个楼号 m 和 n,需要求出它们之间的最短移动距离。(不能斜线方向移动)

输入格式

输入为 33 个整数 �,�,�w,m,n,空格分开,都在 11 到 1000010000 范围内。

w 为排号宽度,�,�m,n 为待计算的楼号。

输出格式

要求输出一个整数,表示 m 与 n 两楼间最短移动距离。

输入输出样例

输入 #1
6 8 2
输出 #1
4
复制代码
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int w,m,n,res=1,ans=1,x,xx,y,yy;
 4 int mp[2020][2020];
 5 bool f1,f2;
 6 int main()
 7 {
 8     cin>>w>>m>>n;
 9     int p=10000/w+1;
10     for(int i=1;i<=p;i++)
11     {
12         if(f1&&f2) break;
13         if(ans%2!=0||ans==1)
14         {
15             for(int j=1;j<=w;j++)
16             {
17                 mp[i][j]=res++;
18                 if(mp[i][j]==m) x=i,y=j,f1=true;
19                 else if(mp[i][j]==n) xx=i,yy=j,f2=true;
20             }
21             ans++;
22         }
23         else if(ans%2==0)
24         {
25             for(int j=w;j>=1;j--)
26             {
27                 mp[i][j]=res++;
28                 if(mp[i][j]==m) x=i,y=j,f1=true;
29                 else if(mp[i][j]==n) xx=i,yy=j,f2=true;
30             }
31             ans++;
32         }
33     }
34     // for(int i=1;i<=7;i++)
35     // {
36     //     for(int j=1;j<=7;j++)
37     //     cout<<mp[i][j]<<" ";
38     //     cout<<endl;
39     // }
40     cout<<abs(x-xx)+abs(y-yy)<<endl;
41     return 0;
42 }
复制代码

P8597 [蓝桥杯 2013 省 B] 翻硬币

题目背景

小明正在玩一个“翻硬币”的游戏。

题目描述

桌上放着排成一排的若干硬币。我们用 * 表示正面,用 o 表示反面(是小写字母,不是零),比如可能情形是 **oo***oooo,如果同时翻转左边的两个硬币,则变为 oooo***oooo。现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢?

输入格式

两行等长字符串,分别表示初始状态和要达到的目标状态,每行长度小于 10001000。

数据保证一定存在至少一种方案可以从初始状态和要达到的目标状态。

输出格式

一个整数,表示最小操作步数。

输入输出样例

输入 #1
**********
o****o****
输出 #1
5
输入 #2
*o**o***o***
*o***o**o***
输出 #2
1
复制代码
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 string s1,s2;
 4 int res;
 5 void filp(int x)
 6 {
 7     if(s1[x]=='*') s1[x]='o';
 8     else s1[x]='*';
 9     if(s1[x+1]=='*') s1[x+1]='o';
10     else s1[x+1]='*';
11 }
12 bool check()
13 {
14     for(int i=0;i<=s1.size();i++)
15     {
16         if(s1[i]!=s2[i]) return false;
17     }
18     return true;
19 }
20 int main()
21 {
22     cin>>s1>>s2;
23     for(int i=0;i<s1.size()-1;i++)
24     {
25         if(check()) break;
26         if(s1[i]!=s2[i])
27         {
28             filp(i);
29             res++;
30         }
31     }
32     cout<<res;
33     return 0;
34 }
复制代码

P9240 [蓝桥杯 2023 省 B] 冶炼金属

题目描述

小蓝有一个神奇的炉子用于将普通金属 O 冶炼成为一种特殊金属 X。这个炉子有一个称作转换率的属性 V,V 是一个正整数,这意味着消耗 V 个普通金属 O 恰好可以冶炼出一个特殊金属 X,当普通金属 O 的数目不足 V 时,无法继续冶炼。

现在给出了 N 条冶炼记录,每条记录中包含两个整数 A 和 B,这表示本次投入了 A 个普通金属 O,最终冶炼出了 B 个特殊金属 X。每条记录都是独立的,这意味着上一次没消耗完的普通金属 O 不会累加到下一次的冶炼当中。

根据这 N 条冶炼记录,请你推测出转换率 V 的最小值和最大值分别可能是多少,题目保证评测数据不存在无解的情况。

输入格式

第一行一个整数 N,表示冶炼记录的数目。

接下来输入 N 行,每行两个整数 �,�A,B,含义如题目所述。

输出格式

输出两个整数,分别表示 V 可能的最小值和最大值,中间用空格分开。

输入输出样例

输入 #1
3
75 3
53 2
59 2
输出 #1
20 25

说明/提示

【样例说明】

当 �=20V=20 时,有:⌊7520⌋=3,⌊5320⌋=2,⌊5920⌋=22075=3,2053=2,2059=2,可以看到符合所有冶炼记录。

当 �=25V=25 时,有:⌊7525⌋=3,⌊5325⌋=2,⌊5925⌋=22575=3,2553=2,2559=2,可以看到符合所有冶炼记录。

且再也找不到比 2020 更小或者比 2525 更大的符合条件的 V 值了。

复制代码
#include<bits/stdc++.h>
using namespace std;
int resmin=-2e9,resmax=2e9;
int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        int a,b;
        cin>>a>>b;
        resmax=min(resmax,a/b);
        resmin=max(resmin,a/(b+1)+1);        
    }
    cout<<resmin<<" "<<resmax;
    return 0;
}
复制代码

 

posted @   o-Sakurajimamai-o  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
-- --
点击右上角即可分享
微信分享提示