填空题

有一说一,今年没只有两个没想到

T1 题A: 九进制转十进制
感觉没啥好说的,逢9进1。ans=93×2+92×0+91×2+2ans = 9^3 \times 2 + 9^2 \times 0 + 9^1 \times 2 + 2

1478 // should 1458 + 18 + 2 = 1,478

T2 题B: 顺子日期
蓝桥杯歧义,建议冲锋

4

大题

我犯了很多错误,已自裁

T1 题C: 刷题统计
送分题,不多说,不开ULL,见祖宗。

#include "iostream"
using namespace std;

#define ULL unsigned long long

ULL a, b, n;

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

  ULL week = 0;
  week = a * 5 + b * 2;

  ULL week_cnt = n / week;
  n = n % week;

  ULL day = 0;
  while (n > 0)
  {
    if (day < 5)
    {
      n -= a;
      day++;
    }
    else
    {
      n -= b;
      day++;
    }
  }
  day += week_cnt * 7;
  cout << day;

  return 0;
}

T2 题D: 修剪灌木
找规律,不会的话可以像我一样,多写点数据,就出来了

#include "iostream"
using namespace std;

#define ULL unsigned long long

ULL tree[10001] = {};

ULL n;

int main()
{
  cin >> n;
  ULL index = n;
  if ((index % 2) == 1)
    index = index / 2 + 1;
  else
  {
    index = index / 2;
  }

  for (int i = 1; i <= index; i++)
  {
    tree[i] = (n - i) * 2;
  }

  for (int i = 1; i <= index; i++)
  {
      cout << tree[i] << endl;
  }

  if ((n % 2) == 1)
    index--;

  for (int i = index; i > 0; i--)
  {
    cout << tree[i] << endl;
  }

  return 0;
}

T3 题E: X 进制减法
看样例,主要是要理解,我手写了120 对应11 5 2 进制的数,就稍微理解了。
求出值一减就行。

#include "iostream"
#define FOREACH(a, b) for (int a = 0; i < b; a++)
#define ULL unsigned long long 
using namespace std;

int N = 0;

int aLen = 0;
int a[1001] = {};

int bLen = 0;
int b[1001] = {};

int base[1001] = {};

ULL an;
ULL bn;

int main()
{
  //freopen("in.txt", "r+", stdin);

  cin >> N;
  cin >> aLen;
  for (int i = 0; i < aLen; i++)
  {
    cin >> a[i];
  }

  cin >> bLen;
  for (int i = 0; i < bLen; i++)
  {
    cin >> b[i];
  }

  //找进制
  for (int i = 0; i < aLen; i++)
  {
    if (a[i] > b[i])
    {
      if (a[i] == 0 || a[i] == 1)
        base[i] = 2;
      else
        base[i] = a[i] + 1;
    }
    else
    {
      if (b[i] == 0 || b[i] == 1)
        base[i] = 2;
      else
        base[i] = b[i] + 1;
    }
  }
  int max = 0, max_index = 0;
  for (int i = 0; i < aLen; i++)
  {
    if (a[i] > max)
    {
      max = a[i];
      max_index = i;
    }
    if (b[i] > max)
    {
      max = b[i];
      max_index = i;
    }
  }
  base[max_index] = N;

  //计算值
  ULL jin = 1;
  for (int i = aLen - 1; i >= 0; i--)
  {

    if (i - (aLen - 1) == 0)
      an += a[i];
    else if (i - (aLen - 1) == 1)
    {
      jin *= base[i + 1];
      an += a[i] * base[i + 1];
    }
    else
    {
      jin *= base[i + 1];
      an += (a[i] * jin) % 1000000007;
    }
  }
  // cout << an << endl;

  jin = 1;
  for (int i = bLen - 1; i >= 0; i--)
  {

    if (i - (bLen - 1) == 0)
      bn += b[i];
    else if (i - (bLen - 1) == 1)
    {
      jin *= base[i + 1];
      bn += b[i] * base[i + 1];
    }
    else
    {
      jin *= base[i + 1];
      bn += (b[i] * jin) % 1000000007;
    }
  }
  // cout << bn << endl;

  cout << (an - bn) % 1000000007 << endl;

  return 0;
}

T4 题F: 统计子矩阵
摆烂没写(实际上是时间不够了),四重for循环也能写出来,但是感觉不是正解。
理论上可以前缀和优化?蓝桥杯必出前缀和来着。

#include "iostream"
#define ULL unsigned long long
using namespace std;

int x, y, N;

int arr[501][501] = {};

ULL cnt = 0;

int main()
{
    cin >> x;
    cin >> y;
    cin >> N;

    for (int i = 0; i < y; i++)
        for (int j = 0; j < x; j++)
        {
            cin >> arr[y][x];
            if(arr[y][x] <= N)
                cnt++;
        }

    // 四重for暴力找
    
    return 0;
}

T5 题G: 积木画
不会,想着可能是DP,找规律恶心我了,写出2*4知道大概有11个?就没写,严格来说就写了读入。
按理来说应该是有规律的,2 5 11。

大佬说是二重前缀和,和大佬贴贴(lianyi超强的,他在友链里面,快去看看

T6 题H: 扫雷
有点长hhh,现场学的map。
爆搜挂着机,可能出现在找圆的时候TIME OUT,我人应该是魔怔了,应该读入的时候做优化的
也就是说。。。优化了炸弹爆炸,应该就可以AC,应该还是遍历MAP树的方式,或者说队列,我是xxx

#include "iostream"
#include "vector"
#include "map"

#define ULL unsigned long long
using namespace std;

int n, m;

typedef struct node
{
  /* data */
  ULL x, y;
  ULL range;
};

map<pair<ULL, ULL>, int> BOOM_map;
map<pair<ULL, ULL>, int> FIRE_map;

node boom[50000];
node fire[50000];

ULL cnt;

//检查是不是炸弹
inline bool cheak(int x, int y)
{
  auto res = BOOM_map.find(pair<ULL, ULL>(x, y));

  if (res == BOOM_map.end())
    return false;
  else
    return true;
}

//以圆圈方式查找炸弹,已经炸的-1
void dfs(int x, int y, int range)
{
  int i = 0, j = 0;
  while (1)
  {
    if (i * i + j * j <= range * range)
    {
      if (cheak(i, j))
      {
        //开炸 dfs寻找
        int range_n = BOOM_map.at(pair<ULL, ULL>(i + x, j + y));
        if (range_n != -1)
        {
          cnt++;
          BOOM_map.at(pair<ULL, ULL>(i + x, j + y)) = -1;
          dfs(i, j, range_n);
        }
      }
      if (cheak(-i, j))
      {
        int range_n = BOOM_map.at(pair<ULL, ULL>(-i + x, j + y));
        if (range_n != -1)
        {
          cnt++;
          BOOM_map.at(pair<ULL, ULL>(-i + x, j + y)) = -1;
          dfs(-i, j, range_n);
        }
      }
      if (cheak(i, -j))
      {
        int range_n = BOOM_map.at(pair<ULL, ULL>(i + x, -j + y));
        if (range_n != -1)
        {
          cnt++;
          BOOM_map.at(pair<ULL, ULL>(i + x, -j + y)) = -1;
          dfs(i, -j, range_n);
        }
      }
      if (cheak(-i, -j))
      {
        int range_n = BOOM_map.at(pair<ULL, ULL>(-i + x, -j + y));
        if (range_n != -1)
        {
          cnt++;
          BOOM_map.at(pair<ULL, ULL>(-i + x, -j + y)) = -1;
          dfs(-i, -j, range_n);
        }
      }

      i++;
      j++;
    }
    else
      break;
  }
}

int main()
{
  cin >> n >> m;
  for (int i = 0; i < n; i++)
  {
    cin >> boom[i].x >> boom[i].y >> boom[i].range;
    BOOM_map.insert(pair<pair<ULL, ULL>, int>(pair<ULL, ULL>(boom[i].x, boom[i].y), boom[i].range));
  }
  for (int i = 0; i < m; i++)
  {
    cin >> fire[i].x >> fire[i].y >> fire[i].range;
    FIRE_map.insert(pair<pair<ULL, ULL>,int>(pair<ULL, ULL>(fire[i].x, fire[i].y), fire[i].range));
  }

  // 遍历火箭map
  for (auto iter : FIRE_map)
  {
    int x = iter.first.first;
    int y = iter.first.second;

    int range = iter.second;
    dfs(x, y, range);
  }

  cout << cnt;

  return 0;
}

T7 题 I: 李白打酒加强版
最后10分钟,没写完,就这样吧,退出有问题,别看了,放着凑字数

#include "iostream"
#define ULL unsigned long long
using namespace std;

ULL N, M; // double sub1

ULL cnt;

ULL jiu = 0;

void dfs()
{
  if (N == 0 && M == 0)
  {
    cnt++;
    cnt %= 1000000007;
    return;
  }
  if (N < 0 || jiu < 0 || M < 0)
    return;

  N = N - 1;
  jiu *= 2;
  dfs();
  N++;
  jiu /= 2;

  M--;
  jiu--;
  dfs();
  jiu++;
  M++;
}

int main()
{
  cin >> N >> M;
  dfs();
  cout << cnt;
  return 0;
}

T8 题J: 砍竹子
有思路,没时间,后面补了注释,就这样吧,有点暴力,但我觉得是对的。
STL不够熟,哈希模板不备,就是这个下场

#include "iostream"
#include "map"
#include "cmath"
#include "vector"
#define ULL unsigned long long
using namespace std;

map<ULL, int> arr; // 高度 数量

unsigned int num;

ULL cntMAX;

void dfs(ULL cnt)
{
  // 如果都为 0 跳出循环
  // 根据cnt 剪枝
  for (auto iter = arr.rbegin(); iter != arr.rend(); iter++)// 问题在于,迭代器失效 似乎砍之后会给有效的迭代器
  {
    // 逆序读取高度 这样才是最高的
    // 砍第一个
    // 没砍到比第二个小的?继续砍
    // dfs
    // 还原第一个
  }
}

int main()
{
  cin >> num;
  for (int i = 0; i < num; i++)
  {
    ULL high;
    cin >> high;
    if (arr.find(high) == arr.end())
      arr.insert(pair<ULL, int>(high, (int)1));
    else
      arr.at(high)++;
  }

  dfs(0);

  cout << cntMAX;

  return 0;
}