首页 > 其他分享 >蓝桥杯之模拟与枚举day1

蓝桥杯之模拟与枚举day1

时间:2023-11-16 20:48:00浏览次数:30  
标签:tmp 10 int flag day1 蓝桥 枚举 && d0

Question1卡片(C/C++A组第一题)

file
这个是一道简单的模拟枚举题目,只要把对应每次的i的各个位都提取出来,然后对应的卡片数目减去1即可。属于打卡题目。注意for循环的特殊使用即可

#include <iostream>
using namespace std;
bool solve(int a[],int n)
{
  //模拟枚举
  while(n!=0)
  {
    int tmp = n % 10;
    n /= 10;
    a[tmp]--;
    if(a[tmp]<0)
      return false;
  }
  return true;
}
int main()
{
  int cnt[10] = {0};
  // 请在此输入您的代码
  for(int i = 0; i <= 9 ;i++)
    cnt[i] = 2021;
  // int ret = 1;
  // bool flag = true;
  // flag = solve(cnt,1);
  // while(flag)
  // {
  //   ret++;
  //   flag = solve(cnt,ret);
  // }
  /*
  也可以用for循环
  */
  for(int i = 1; ;i++)
    if(!solve(cnt,i)){
	cout<<i-1<<endl;
	return 0;}
  //记得最后要减去1
  // cout<<ret-1<<endl;
  return 0;
}

file

Question2回文日期(C/C++A组第七题)

file
在蓝桥杯官网上面显示这个题目属于困难,但是实际上很简单。直接枚举就行,但是注意要如何进行枚举,日期30进1,月份12进1。想清楚这个就是很简单的枚举了

//
// Created by jjh on 2023/11/10.
//
#include<iostream>
using namespace std;
/*
思路:
1、难点在于日期的遍历,要考虑好怎么进行进位
2、回文日期的判断,用一个八位数组就行
3、ABABBABA型特殊判断
*/
bool huiwen(int d)//回文字符串
{
    int a[8];
    for(int i = 0; i < 8; i++)
    {
        int tmp = d % 10;
        a[7 - i] = tmp;
        d = d / 10;
    }
    int i = 0;
    while(a[i] == a[7-i])
        i++;
    return i>4;
}
bool huiwen1(int d)//特殊回文串判断
{

    int a[8];
    for(int i = 0; i < 8; i++)
    {
        int tmp = d % 10;
        a[7 - i] = tmp;
        d = d / 10;
    }
    if(a[0] == a[2] && a[2] == a[5] && a[5] == a[7] )
        if(a[1] == a[3] && a[3] == a[4] && a[4] == a[6])
            if(a[0]!=a[1])
                return true;
    return false;
}
int main(){
    /*
    遍历日期,年 月 日
    日是30进一位,月是12进一位
    */
    bool flag = false,flag1 = false;
    int ans1 = 0,ans = 0,d0;
    string d;
    cin>>d;
    d0 = stoi(d);//转化为数组
    int first = d0;
    while(true)
    {
        if(huiwen(d0)&&!flag&&d0!=first){
            ans = d0;
            flag = true;
        }
        if(huiwen1(d0)&&!flag1&&d0!=first)
        {
            ans1 = d0;
            flag1 = true;
        }
        if(flag&&flag1)
        {
            cout<<ans<<endl<<ans1<<endl;
            return 0;
        }
        int tmp = d0 % 100;//获取日期最后两位
        tmp++;
        if(tmp > 30)
        {
            int tmp1 = d0/100;
            int tmp2 = tmp1;
            tmp1 %= 100;
            tmp1++;
            if(tmp1 > 12)
            {
                d0 = (((tmp2/100)+1)*100 + 1)*100 + 1;
                continue;
            }
            else
            {
                d0 = (tmp2 +1)*100 + 1;
                continue;
            }
        }
        d0++;
    }

    return 0;
}

Question3(C/C++A组第四题)赢球票

file
这个也是一道模拟的题目,难点在于如何拆分问题。面对这个问题,要有几个思考。

怎么在链上模拟环的移动?

这个是好办的,当pos = n的时候,我们将其归为为1即可。pos = 1

如何表示被拿走的卡片?

被拿走的卡片我们是不能访问计数的,用一个flag数组表示即可解决问题,但是在不同位置开始遍历的时候记得清零

哪个位置开始取得最大值?

这个问题我们是不知道的,所以要进行枚举,每一个位置都模拟一轮

游戏如何结束?

当我们选择的卡片数量为n的时候或者当我们数到的数比所有卡片的数量还要多!

tips:注意输出的答案不是能选择的最多卡片数目,而是能够赢得的最多球票数目,及卡片所代表的值!

代码:

//
// Created by jjh on 2023/11/10.
//
#include <iostream>
#include <cstring>

using namespace std;
/*
 * 思路:
 * 1、数组模拟环上面的移动
 * 2、flag[i] = 1表示i处已经被移走
 * 3、当已经移走所有卡片或者当前数的数大于n
 * */
int main(){
    int n,maxx = INT_MIN;
    cin>>n;
    int flag[n+1],a[n+1];

    memset(a,0,sizeof(a));
    for(int i = 1; i <= n; i++)
        cin>>a[i];
    for(int i = 1; i <= n; i++)
    {
        memset(flag,false,sizeof(flag));
        int pos = i,cnt = 1,ans = 0,sum = 0;
//        while(cnt <= n && ans < n)
            while(1)
            {
              if(!flag[pos])
              {
                  if(a[pos] == cnt)
                  {
                      sum += a[pos];
                      flag[pos] = true;
                      pos++;
                      ans++;
                      if(pos > n)
                          pos = 1;
                      cnt = 1;
                  }else
                  {
                      cnt++;
                      pos++;
                      if(pos > n)
                          pos = 1;
                  }
              }
              else
              {
                  pos++;
                  if(pos > n)
                      pos = 1;
              }
                if(cnt > n || ans == n)
                    break;
            }
            maxx = max(maxx,sum);

    }
    cout<<maxx<<endl;
    return 0;
}

Question4(C/C++A组第二题)

file
实质上就是看你会不会求最大公约数!打卡题

//
// Created by jjh on 2023/11/10.
//
#include <iostream>
using namespace std;
/*
 * 思路:本质上就是一个判断最大公约数的题目,暴力枚举就行
 * */
int check(int i,int j)
{
    return j == 0 ? i : check(j,i%j);
}
long long ans;
int main(){
    for(int i = 1; i <= 2020;i++)
        for(int j = 1; j <= 2020;j++)
            if(check(i,j) == 1)
                ans++;
    cout<<ans<<endl;
    return 0;
}

Question5(C/C++A组第4题)数的分解

file
这个显然是一个暴力枚举法,记得去重就可。

易得:

   for(int i = 1; i <= 2019;i++)
        for(int j = 1 ;j <= 2019 ;j++)
            for(int k = 1; k <= 2019;k++)
                if(i + j + k == 2019 && !check(i)&&!check(j)&&!check(k)&&i!=j&&j!=k&&i!=k)
                    ans++;
       ans/=6;

但是这个复杂度太高了,那能不能进行优化呢?当然是可以的!

首先我们可以确定i,j,k的次序,省去去重操作了。

还有就是我们可以利用flag数组提前计算出哪些数字包含有2/4。进一步,我们实际上可以利用两重循环来解决问题,k那层直接用 2019 -i - j代替.!

//
// Created by jjh on 2023/11/10.
//
#include <iostream>
using namespace std;
int n;
/*
 * 题目关键点:
 * 1、如何去重
 * 2、如何判断是否含有数字2或者4
 * */
bool check(int n)
{
    bool flag = false;
    while(n!=0&&!flag)
    {
        int tmp = n % 10;
        n /= 10;
        if(tmp == 2 || tmp == 4)
            flag = true;
    }
    return flag;
}
long long ans;
bool flag[2020];
int main(){

    for(int i = 1 ;i <= 2019;i++)if(check(i))flag[i] = true;
//    for(int i = 1; i <= 2019;i++)
//        for(int j = 1 ;j <= 2019 ;j++)
//            for(int k = 1; k <= 2019;k++)
//                if(i + j + k == 2019 && !check(i)&&!check(j)&&!check(k))
//                    ans++;
    //去重

//    cout<<ans / 6<<endl;
    for(int i = 1; i <= 2019;i++)
        for(int j = i+1;j < 2019 - i - j;j++)
            if(!flag[i] && !flag[j] &&!flag[2019 - i - j])
                ans++;
    cout<<ans<<endl;
    return 0;
}

本文由博客一文多发平台 OpenWrite 发布!

标签:tmp,10,int,flag,day1,蓝桥,枚举,&&,d0
From: https://www.cnblogs.com/xiaocrblog/p/17837214.html

相关文章

  • Day1
    快捷键Ctrl+C复制Ctrl+V粘贴Ctrl+A全选Ctrl+X剪切Ctrl+Z撤销Ctrl+S保存Alt+F4关闭窗口Shift+Delete永久删除Window+R运行窗口(可以打开cmd)Window+E我的电脑Window+Tab切换应用程序Ctrl+Shift+Esc任务管理器Dos命令1)打开cmd的方......
  • 枚举策略模式
    枚举策略模式将枚举和策略模式相结合,能使代码更加简洁。以下是消息推送相关的案例1、定义消息推送接口packagecom.bitzh.strategy;publicinterfaceMessagePushStrategy{voidpush(Stringcontent);}2、分别创建邮件推送、短信推送和企业微信推送三个类,实现消息......
  • 【每日例题】 蓝桥杯 c++ 冶炼金属
    冶炼金属题目小蓝有一个神奇的炉子用于将普通金属О冶炼成为一种特殊金属X。这个炉子有一个称作转换率的属性V,V是一个正整数,这意味着消耗V个普通金属О恰好可以冶炼出一个特殊金属X,当普通金属О的数目不足V时,无法继续冶炼。现在给出了Ⅳ条冶炼记录,每条记录中包含两个整数A和B,这......
  • P9242 [蓝桥杯 2023 E题] 接龙数列
    P9242[蓝桥杯2023E题]接龙数列一眼LIS但是TLE八个点。发现是sb了,应该用string来存数直接取首位末位。改完50分,TLE五个点。换状态\[F_i$$为以数字$i$结尾的最长接龙数列。则顺推每个数字,从每个数字的首位$F_{j_1}+1$以及末位$F_{j_n}$中取最大转移而来。即......
  • 蓝桥杯管道 -- 二分, 区间覆盖
    蓝桥杯管道--二分,区间覆盖原题链接参照执梗大佬的代码,我太菜了wuwuwu......importjava.util.ArrayList;importjava.util.Collections;importjava.util.List;importjava.util.Scanner;/***ClassName:Main12*Package:*Description:**@author:LH寒酥......
  • day130-springboot的各种配置与应用
    编写springboot应用看官方文档DevelopingwithSpringBoot查看场景依赖,引入对应自动配置的场景,编写配置文件中debug=true开启自动配置报告。Negative(不生效)Positive(生效)Lombok的应用Lombok用标签方式代替构造器、getter/setter、toString()等鸡肋代码。引入依赖......
  • 枚举和注解
    枚举和注解枚举是一组常量集合可以理解:枚举属于一种特殊的类,里面直包含一组有限的特定的对象自定义类实现枚举使用enum关键字实现枚举自定义枚举实现不需要提供setXXXX方法,因为枚举对象值通常为只读对枚举对象/属性使用final+static共同修饰,实现底层优化......
  • Day1
    快捷键Ctrl+C复制Ctrl+V粘贴Ctrl+A全选Ctrl+X剪切Ctrl+Z撤销Ctrl+S保存Alt+F4关闭窗口Shift+Delete永久删除Window+R运行窗口(可以打开cmd)Window+E我的电脑Window+Tab切换应用程序Ctrl+Shift+Esc任务管理器......
  • 【每日例题】蓝桥杯 c++ 小郑下五子棋
    小郑下五子棋题目五子棋是—种两人对弈的棋类游戏,它使用黑白两种棋子在一个20×20的棋盘上进行。黑方执黑棋,白方执白棋。双方轮流下棋,目标是先在横向、纵向或斜向连成五个己颜色的棋子,即五子相连,即可获胜。五子棋是—种简单却富有策略的游戏,常常被用于智力训练和竞技比赛。这不,......
  • day10 函数基础
    day10函数入门目标:掌握函数的编写方式以及函数的基本使用。今日概要:初识函数函数的参数函数的返回值提示:由于昨天的内容比较多,为了减轻大家的学习压力,今天设计的课程内容会比较少。1.初识函数函数到底是个什么东西?函数,可以当做是一大堆功能代码的集合。def函数......