首页 > 其他分享 >P8714 题解

P8714 题解

时间:2023-05-09 11:56:21浏览次数:44  
标签:return P8714 int 题解 31 back ++ push

洛谷 P8714

题意

自己看(

思路

分五个小题去考虑。

问题 A

枚举门牌号,看门牌号中有多少个 \(2\),统计答案即可。

void sloveA () { // 问题 A
  int sum = 0;
  for (int i = 1, j; i <= 2020; i++) { // 枚举门牌号
    j = i;
    while (j) { // 枚举每一位
      sum += (j % 10 == 2); // 统计 2 的数量
      j /= 10;
    }
  }
  cout << sum;
}

输出答案:\(624\)。

问题 B

枚举分子和分母,判断分子分母是否互质,统计互质的分子分母对数。

int gcd (int x, int y) { // 欧几里得算法求最小公因数
  return (y ? gcd(y, x % y) : x);
}
void sloveB () { // 问题 B
  int sum = 0;
  for (int i = 1; i <= 2020; i++) {
    for (int j = 1; j <= 2020; j++) { // 先枚举分子分母
      sum += (gcd(i, j) == 1); // 判断是否互质
    }
  }
  cout << sum;
}

输出答案:\(2481215\)。

问题 C

开始有难度了哟。

首先画一个草图:

经过观察,我们可以发现:对于每个整数 \(x\),位于 \((x,x)\) 的数所在的红线箭头都是从下往上的。

那么答案要求的那个数必然也在一条从下往上的红线上。

再观察一下,贯穿 \((x,x)\) 的红线起始点在 \((2x - 1,1)\) 上。

再推一下,假设我们现在求的是位于 \((3,3)\) 的数,可以发现:

这里有一个三角形,三角形中的数的个数再加上 \(x\) 就是答案!三角形中的数的个数也很好求,就是 \(1 + 2 + 3 + \cdots + (2x - 2)\)。

综上所述,求位于 \((x,x)\) 的数的公式就是 \((1 + 2x - 2) \times (2x - 2) / 2 + x\)。

void sloveC () { // 问题 C
  int x = 20 * 2 - 1;
  cout << (x * (x - 1) / 2 + 20); // 套用公式
}

输出答案:\(761\)。

问题 D

模拟一下,有些细节,处理号闰年和星期等问题就行了。具体看代码。

const int D[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // 每一个月的天数

bool leap (int y) { // 判断闰年,如果是闰年则返回值为 1,否则返回值为 0
  if (y % 100) { // 不是整百年
    return !(y % 100 % 4);
  }
  y /= 100; // 是整百年
  return !(y % 4);
}
bool check (int y, int m, int d) { // 判断是否已经求完了所有日子。
  return !(y == 2020 && m == 10 && d == 2); // 因为包含了 2020.10.1,所以要往后一天
}
void sloveD () { // 问题 D
  int y = 2000, m = 1, d = 1, z = 6, ans = 0; // y 为年份,m 为月份,d 为日期,z 为星期几,ans 为答案
  while (check(y, m, d)) { // 判断
    ans++; // 每天至少跑 1 km
    if (z == 1 || d == 1) { // 特殊日子
      ans++; // 再跑 1 km
    }
    d++, z = z % 7 + 1; // 处理日期变更
    if (m != 2 || !leap(y)) { // 不是二月或不是闰年
      if (d == D[m] + 1) { // 正常处理
        m++, d = 1;
      }
    } else { // 是闰二月
      if (d == 30) { // 特殊处理
        m++, d = 1;
      }
    }
    if (m == 13) { // 一年又过完了
      y++, m = 1; // 新的一年!
    }
  }
  cout << ans;
}

输出答案:\(8879\)。

问题 E

看了一下题解区,实现也没简单到哪去,枚举一下每个二极管亮或不亮,从某一个亮着的二极管开始做一次深搜,判断是否可以只通过亮着的二极管走到所有二极管。

先建一张图我蠢了用了个邻接表,可以通过枚举二进制数来方便的枚举每种情况,统计答案即可。

void dfs (int x) { // 简单 dfs
  if (vis[x] || !f[x]) {
    return ;
  }
  vis[x] = 1, num++;
  for (int i : v[x]) {
    dfs(i);
  }
}
void sloveE () { // 问题 E
  int sum = 0;
  pret(); // 预处理
  for (int i = 1; i < (1 << 7); i++) { // 枚举二进制对应的十进制数
    int st = 7, cnt = 0; // st 为任意的一个亮着的二极管,我就编号取最小的一个
    num = 0;
    for (int j = 0; j < 7; j++) { // 二进制拆分
      f[j] = ((i >> j) & 1), vis[j] = 0;
      if (f[j]) {
        st = min(st, j), cnt++;
      }
    }
    dfs(st); // 做一次深搜
    sum += (num == cnt); // 如果能够找到所有发光二极管,答案加 1
  }
  cout << sum;
}

输出答案:\(80\)。

好了,到这里,所有小题全部解决了,总体代码 \(126\) 行,对我来说是比较长的了。

完整代码

#include <iostream>
#include <vector>

using namespace std;

const int D[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // 每一个月的天数

char c;
vector<int> v[10];
bool vis[10], f[10];
int num;

void pret () { // 日常犯蠢 1/1
  v[0].push_back(1), v[0].push_back(5);
  v[1].push_back(0), v[1].push_back(2), v[1].push_back(6);
  v[2].push_back(1), v[2].push_back(3), v[2].push_back(6);
  v[3].push_back(2), v[3].push_back(4);
  v[4].push_back(3), v[4].push_back(5), v[4].push_back(6);
  v[5].push_back(0), v[5].push_back(4), v[5].push_back(6);
  v[6].push_back(1), v[6].push_back(2), v[6].push_back(4), v[6].push_back(5);
}
int gcd (int x, int y) { // 欧几里得算法求最小公因数
  return (y ? gcd(y, x % y) : x);
}
bool leap (int y) { // 判断闰年,如果是闰年则返回值为 1,否则返回值为 0
  if (y % 100) { // 不是整百年
    return !(y % 100 % 4);
  }
  y /= 100; // 是整百年
  return !(y % 4);
}
bool check (int y, int m, int d) { // 判断是否已经求完了所有日子。
  return !(y == 2020 && m == 10 && d == 2); // 因为包含了 2020.10.1,所以要往后一天
}
void dfs (int x) { // 简单 dfs
  if (vis[x] || !f[x]) {
    return ;
  }
  vis[x] = 1, num++;
  for (int i : v[x]) {
    dfs(i);
  }
}

void sloveA () { // 问题 A
  int sum = 0;
  for (int i = 1, j; i <= 2020; i++) { // 枚举门牌号
    j = i;
    while (j) { // 枚举每一位
      sum += (j % 10 == 2); // 统计 2 的数量
      j /= 10;
    }
  }
  cout << sum;
}
void sloveB () { // 问题 B
  int sum = 0;
  for (int i = 1; i <= 2020; i++) {
    for (int j = 1; j <= 2020; j++) { // 先枚举分子分母
      sum += (gcd(i, j) == 1); // 判断是否互质
    }
  }
  cout << sum;
}
void sloveC () { // 问题 C
  int x = 20 * 2 - 1;
  cout << (x * (x - 1) / 2 + 20); // 套用公式
}
void sloveD () { // 问题 D
  int y = 2000, m = 1, d = 1, z = 6, ans = 0; // y 为年份,m 为月份,d 为日期,z 为星期几,ans 为答案
  while (check(y, m, d)) { // 判断
    ans++; // 每天至少跑 1 km
    if (z == 1 || d == 1) { // 特殊日子
      ans++; // 再跑 1 km
    }
    d++, z = z % 7 + 1; // 处理日期变更
    if (m != 2 || !leap(y)) { // 不是二月或不是闰年
      if (d == D[m] + 1) { // 正常处理
        m++, d = 1;
      }
    } else { // 是闰二月
      if (d == 30) { // 特殊处理
        m++, d = 1;
      }
    }
    if (m == 13) { // 一年又过完了
      y++, m = 1; // 新的一年!
    }
  }
  cout << ans;
}
void sloveE () { // 问题 E
  int sum = 0;
  pret(); // 预处理
  for (int i = 1; i < (1 << 7); i++) { // 枚举二进制对应的十进制数
    int st = 7, cnt = 0; // st 为任意的一个亮着的二极管,我就编号取最小的一个
    num = 0;
    for (int j = 0; j < 7; j++) { // 二进制拆分
      f[j] = ((i >> j) & 1), vis[j] = 0;
      if (f[j]) {
        st = min(st, j), cnt++;
      }
    }
    dfs(st); // 做一次深搜
    sum += (num == cnt); // 如果能够找到所有发光二极管,答案加 1
  }
  cout << sum;
}

int main () {
  // freopen("output", "w", stdout);
  ios::sync_with_stdio(0), cin.tie(0);
  cin >> c;
  if (c == 'A') {
    sloveA();
  } else if (c == 'B') {
    sloveB();
  } else if (c == 'C') {
    sloveC();
  } else if (c == 'D') {
    sloveD();
  } else {
    sloveE();
  }
  return 0;
}

或者:

#include<iostream>

using namespace std;

int ans[5] = {624, 2481215, 761, 8879, 80};
char c;

int main() {
  cin >> c;
  cout << ans[c - 'A'];
  return 0;
}

标签:return,P8714,int,题解,31,back,++,push
From: https://www.cnblogs.com/lw0-blog/p/17384459.html

相关文章

  • 第十四届蓝桥杯省赛C++ B组(个人经历 + 题解)
    参赛感受这是我第一次参加蓝桥杯的省赛,虽然没什么参赛经验,但是自己做了很多前几届蓝桥杯的题,不得不说,这一届蓝桥杯省赛的难度相较于之前而言还是比较大的。之前很流行蓝桥杯就是暴力杯的说法,但是随着参赛人数的增多,比赛认可度的提升,比赛题目的质量也明显越来越高了。这次省赛涉及......
  • CF920E Connected Components? 题解
    一道线段树优化建图好题(大雾扣掉一些边看起来不好做,我们直接大力加上存在的边,然后跑连通块。对于一个点,如果他被扣掉了\(k\)个邻居,那么没扣掉的那些形成了至多\(k+1\)个连续段,可以用线段树优化建图向每个连续段各用\(\log\)的代价连边。由于总共扣掉了\(m\)条边,所以总共......
  • 装最多水的容器 - 题解
    1.问题描述  原题的地址见:ContainerWithMostWater-LeetCode.此问题等价于如下问题:    给定所有元素非负的数组[a0,a1,...,an-1],计算(j-i)|aj-ai|(其中j>i)的最小值。 2.暴力解法  有了问题的描述,很容易写出暴力求解的算法:intmaxArea(vector<int>......
  • Windows 安装 pycrypto 常见问题解决
    关于python使用Crypto.Cipher模块,ImportError:Nomodulenamed'Crypto' 常见问题解决1. 需要安装:MicrosoftVisualC++14.0error:MicrosoftVisualC++14.0isrequired.Getitwith"MicrosoftVisualC++BuildTools":http://landinghub.visualstudio.co......
  • CF1794D 题解
    一、题目描述:一个正整数$m$可以被唯一分解成$p_1^{e_1}\timesp_2^{e_2}\times...\timesp_k^{e_k}$的形式,其中$p_1,p_2,...,p_k$为互不相同的质数,$e_1,e_2,...,e_k$为正整数。定义一个可重集$f(m)$为$\{p_1,e_1,p_2,e_2,...,p_k,e_k\}$。现在给定正整数$......
  • 51nod 1365 Fib(N) mod Fib(K)-题解
    51nod1365Fib(N)modFib(K)个人评价:考一些奇奇怪怪的知识点呢算法矩阵快速幂、斐波那契公式题面求\(F_n\%F_k\)的值,\(1\leqn,k\leq1e18\)问题分析我一开始居然想着直接矩阵快速幂求出两个值算,我也是真的牛……我们要知道这些斐波那契公式(考的真怪)\[F_{-n}=(-1)^{n......
  • 2023ccpc湖北省赛/2023 Hubei Provincial Collegiate Programming Contest个人题解
    2023HubeiProvincialCollegiateProgrammingContestAPrimeMagicWalkAlonehasasequence\(a_1,a_2,...,a_n\),andhecanuseamagiconit:Chooseanoddprimenumber\(p\)andaninterval\([l,r]⊆[1,n]\)satisfying\(r−l+1=p\),andthenadd......
  • MultiDex使用方法及由此导致的crash、ANR问题解决方案
    Android开发的朋友,如果是在开发一款中大型应用时,都会碰到这么一个问题,就是dex分拆问题,google给出的解决方案MultiDex。现象:有些APP本身功能比较多,再加上一些其它三方的SDK,慢慢的发现dex越来越大,直到有一天编译出现如下错误:Error:Thenumberofmethodreferencesina.dexfile......
  • 十二代酷睿处理器N100 N200 N305 等安装ESXI紫屏问题解决办法
    12代大小核紫屏报错解决方案四部曲1、安装界面倒计时结束之前,按SHIFT+O,在原有命令后面加空格后输入以下代码cpuUniformityHardCheckPanic=FALSE2、安装完ESXI之后会重启,在重启界面倒计时结束前,再操作一次,按住SHIFT+O,输入cpuUniformityHardCheckPanic=FALSE3、进入ESXI把SSH功能......
  • 力扣《环形链表Ⅱ》超详细题解
    作为经典题目的《环形链表Ⅱ》,我认为这题还是有专门出一期博客的分量的,大家也可以自己事先按照自己的理解写一写,然后再来看题解,毕竟自己悟出来的东西是比吸收别人的来的更深刻。一、题目给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。......