蓝桥杯2024国赛--备赛刷题题单

1.游戏(单调队列)

注意如果结果是分数,直接设置变量为double,最好不要使用把int类型乘1.0变成分数来计算。

#include <iostream>
#include <queue>
using namespace std;
const int N=1e5+10;
//滑动窗口大小为k,最大值为P,最小值为Q,K=P-Q
//窗口个数为cnt=n-k+1
//所有情况为all=cnt*cnt
//期望值为(K1+K2+...+Kall)/all
//由于熊大选框和熊二选框的情况是一样的,因此只需要
//(K1+K2+...+Kcnt)/cnt
int a[N];
int wd[N];
deque<int>q;//双端队列
int main()
{
  int n,k;
  scanf("%d %d\n",&n,&k);
  for(int i=1;i<=n;i++)
  {
    scanf("%d",&a[i]);
  }
  double sump=0;//窗口最大值加和
  for(int i=1;i<=n;i++)
  {
    while(!q.empty()&&a[q.back()]<a[i])q.pop_back();
    q.push_back(i);//4 3 2 1...(从大到小的窗口)a[i]<=a[q.back()]才加入
    if(i>=k)//大于等于窗口大小才开始计算答案
    { //不在窗口内的下标pop掉
      while(!q.empty()&&q.front()<=i-k)q.pop_front();
      sump+=a[q.front()];
    }
  }
  q.clear();//注意要把队列清空!
  double sumq=0;//窗口最小值加和
  for(int i=1;i<=n;i++)
  {
    while(!q.empty()&&a[q.back()]>a[i])q.pop_back();
    q.push_back(i);//1 2 3 4...(从小到大的窗口)a[i]>=a[q.back()]才加入
    if(i>=k)//大于等于窗口大小才开始计算答案
    { //不在窗口内的下标pop掉
      while(!q.empty()&&q.front()<=i-k)q.pop_front();
      sumq+=a[q.front()];
    }
  }
  printf("%.2lf\n",(sump-sumq)/(n-k+1));
  return 0;
}

2.01游戏(DFS剪枝)

#include<iostream>
using namespace std;
char a[15][15];
bool flag=0;
int n;
bool check()
{
  //判断行
  for(int i=0;i<n;i++)
  {
    int cnt0=0,cnt1=0;//记录连续出现
    int sum0=0,sum1=0;
    for(int j=0;j<n;j++)
    {
      if(a[i][j]=='_')cnt1=0,cnt0=0;//连续中断
      else if(a[i][j]=='1'){
        cnt1++;
        sum1++;
        cnt0=0;
      }else if(a[i][j]=='0'){
        cnt0++;
        sum0++;
        cnt1=0;
      }
      if(cnt1>2||cnt0>2)return 0;
      if(sum1>n/2||sum0>n/2) return false;//超过一半就无法保证数量相等
    }
  }
   //判断列
  for(int i=0;i<n;i++)
  {
    int cnt0=0,cnt1=0;//记录连续出现
    int sum0=0,sum1=0;
    for(int j=0;j<n;j++)
    {
      if(a[j][i]=='_')cnt1=0,cnt0=0;//连续中断
      else if(a[j][i]=='1'){
        cnt1++;
        sum1++;
        cnt0=0;
      }else if(a[j][i]=='0'){
        cnt0++;
        sum0++;
        cnt1=0;
      }
      if(cnt1>2||cnt0>2)return 0;
      if(sum1>n/2||sum0>n/2) return false;//超过一半就无法保证数量相等
    }
  }
  return 1;
}
void dfs(int x,int y)//默认是先向右走再向下走
{
  if(flag)return;
  if(y==n)
  {
    x++;//再向下
    y=0;//再从左边起始开始
  }
  if(x==n)
  {
    //到达右下角了可以输出答案
    flag=1;
    for(int i=0;i<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值