A

添加链接描述

B-平方斐波那契

题意:给你个数n,回答第n个斐波那契数是不是平方数
斐波那契数定义为f1=1,f2=1,f3=f1+f2…fn=fn-1+fn-2
思路:有一个很明显的性质是只有1和144是平方数,其余都不是平方数

#include<bits/stdc++.h>
using namespace std;
int main()
{long long n ;cin >> n ;if(n == 1 || n == 2 || n == 12) puts("1");else puts("0");return 0 ;
}

问题 C: 逃学的小孩

(在CSDN搜这道题的话可能会出现什么树的直径的做法,但是本人太菜了所以就只复述下东子哥的两次遍历吧)

题意解读:
很明显,这道题的结构模型是树,并且2<=n<=200000。第一眼看上去的话,首先应该找三个点,那就遍历所有的节点,找出距离它最远的两点即可……但是,在树形结构上, 计算出离某个节点最远的两个节点需要 O(n) 的复杂度,而我们还需要遍历树中所有的点(并不知道哪一点最优),这样一来,时间复杂度就成了O(n2),抱歉,超时。

那应该对节点进行怎样的操作呢?找到距离此节点最远的三个最长距离,并且可以保证这三条最远路径必然在当前节点的三个不同的子树中(题目保证任两个居住点间有且仅有一条通路),但是只是单纯枚举所有节点去求其对应的最长距离……好像又会超时,因此这里需要改变一下思路,对树进行两次遍历:

那就随便定一个点作为根节点,然后进行第一次的dfs,算出每个节点的所有子树中所能到达的最远的三个距离;
注意此次遍历忽略了从当前节点的父节点这一分支,因此在这里需要进行第二次dfs,将这条被忽略的路径也添加到所维护的距当前节点最远的三条路径中。

在这之后就是遍历所有节点,寻找最优解的过程了。详细流程看代码:

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=400010;
int n;
long long m;
int h[N],ne[N],e[N],idx;//运用链表存储边
long long w[N];
long long ma[N][5];//存储此节点所能到达的三条最远距离
void add(int a,int b,long long c)
{e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;return ;
}//新建边
void dfs1(int u,int up)
{for(int i=h[u];i!=-1;i=ne[i]){int v=e[i];if(v==up) continue;dfs1(v,u);if(ma[v][0]+w[i]>ma[u][2]){ma[u][2]=ma[v][0]+w[i];sort(ma[u],ma[u]+3,greater<long long>());}}return ;
}//第一次循环,从根节点开始深搜, 算出子树到当前节点的三条最远距离
void dfs2(int u,int up,long long mag)
{if(ma[u][2]<mag){ma[u][2]=mag;sort(ma[u],ma[u]+3,greater<long long>());}//将从父节点那边到达的最远距离加入到三条路径中 for(int i=h[u];i!=-1;i=ne[i]){int v=e[i];if(v==up) continue;if(ma[u][0]==ma[v][0]+w[i]) dfs2(v,u,ma[u][1]+w[i]);else dfs2(v,u,ma[u][0]+w[i]);//这里把父节点所能到达的最远距离传到子节点那里时,//要判断这个最远距离是否原本就是从这个子节点传上来的 }return ;
}
int main()
{scanf("%d %lld",&n,&m);memset(h,-1,sizeof h);memset(ma,0,sizeof ma);int a,b;long long c;while(m--){scanf("%d %d %lld",&a,&b,&c);add(a,b,c);add(b,a,c);}dfs1(1,0);dfs2(1,0,0);long long res=0;for(int i=1;i<=n;i++)res=max(res,ma[i][0]+2*ma[i][1]+ma[i][2]); //遍历所有节点,求最优解 /**这里东子哥原本的思路是特判当前节点有(1、2、>=3)条边,然后我初始化ma数组均为零,勉强糊弄过去了……**/printf("%lld",res);// for(int i=1;i<=n;i++)// printf("%lld %lld %lld\n",ma[i][0],ma[i][1],ma[i][2]);return 0;
}

问题 D: 行列式

题意解读:
解题思路都在线代书里,不用多说了吧……
好像直接搜行列式解法的话会用到逆序数之类的,不过咱也不懂,就把高斯消元的码挂下面了。
详细步骤就是先模拟手动化简行列式为上三角行列式,然后将主对角线上的元素相乘,完事。
注意事项有三:

  1. 不要用double,否则会爆精度 (悲);
  2. 看到mod,就该想到运用 逆元 ,即将对一个数的除法转换为对这个数的逆元的乘法,因为只需要将高斯消元中的除法全部换掉就行,在这里就不废话了;
  3. 其实不会用逆元也可以用下辗转相除法,这是用来求最大公约数的板子,在这里可以用来处理行列式的两列相消,意外的好用,下面是这种方法的码(人菜码多别骂了)。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int N=510;
int n;
long long m;
long long s[N][N];
long long ans=1;
void grd(int a,int b,int c)
{if(s[b][c]!=0){long long t=s[a][c]/s[b][c];s[a][c]%=s[b][c];for(int i=c+1;i<n;i++)s[a][i]=(s[a][i]-t*s[b][i])%m;grd(b,a,c);}return ;
}
long long gauss()
{int c,r;// c 代表 列 col , r 代表 行 rowfor(r=0,c=0;c<n;c++){int t=r;for(int i=r;i<n;i++)if(llabs(s[i][c])>llabs(s[t][c])) t=i;//找当前列的最大值 if(llabs(s[t][c])==0) break;//如果最大是0的话,说明次行列式的秩 < n ,行列式值必然是零 if(t!=r){for(int i=c;i<n;i++) swap(s[t][i],s[r][i]);ans*=-1;}if(s[r][c]<0) {for(int i=c;i<n;i++) s[r][i]*=-1;ans*=-1;}for(int i=r+1;i<n;i++) {if(s[i][c]<0) {for(int j=c;j<n;j++) s[i][j]*=-1;ans*=-1;}if(s[i][c]==0) continue; grd(r,i,c);if(s[r][c]==0){for(int j=c;j<n;j++) swap(s[r][j],s[i][j]);ans*=-1;}}           r++;}if(r<n) return 0;for(int i=0;i<n;i++)ans=(long long)(ans*s[i][i]%m+m)%m;return (ans%m+m)%m;
}
int main()
{scanf("%d %lld",&n,&m);for(int i=0;i<n;i++)for(int j=0;j<n;j++)scanf("%lld",&s[i][j]);long long t=gauss();if(t==0)printf("0");else printf("%lld",t);return 0;
}

E: 二叉树的宽度

题意:我们定义:二叉树每一层中,节点最多的那层的节点数为二叉树的宽度。 每行输入一棵二叉树的带虚结点(#)表示的前序遍历序串,长度不超过2000。每个结点为一个小写字母或一个数字。请编写一个程序计算二叉树的宽度。
思路:首先来看看二叉树的图

1 可以看到第一层的第一个节点是1(从2的0次方-2的1次方-1)
第二层的节点是2到3 (从2的1次方-2的2次方-1)
第三层的节点是4到7 (从2的2次方-2的3次方-1)
第四层的节点是8到15 (从2的3次方-2的4次方-1)
第n层的节点是从2的n-1次方到2的n次方-1
2 除次之外 对于每一个节点
它的左儿子是它的2倍
它的右儿子是它的2倍+1
3 树有三种遍历方式 前/中/后序遍历
前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树。
若二叉树为空则结束返回,否则:
(1)访问根结点。
(2)前序遍历左子树。
(3)前序遍历右子树 。
需要注意的是:遍历左右子树时仍然采用前序遍历方法。
如所示二叉树

前序遍历结果:ABDECF
所以给定一个前序遍历+带虚节点
可以用数组保存数的方式+递归建立这棵树
由于在递归的过程中,节点以指数增长
可能会爆空间,所以数组要改成map进行离散化,防止空间复杂度太高
然后建立这颗树之后,对每一层统计节点个数
在更新最大值

#include<bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define re register int
typedef long long ll ;
using namespace std;
const int N = 2010 , M = 1e6 + 10 ;
char s[M] ;
int a[M] ;
int k = 1 ;
unordered_map<int,int> x ;
int n ;
void dfs(int u)
{if(s[k] == '#') return ;if(s[k] != '#'){   x[u] = 1 ;k ++ ;dfs(u << 1) ;k ++ ;dfs(u << 1 | 1);}
}
int main()
{for(int i = 0 ; i <= 20 ; i ++) a[i] = 1 << i ;while(cin >> s + 1 ){n = strlen(s + 1) ;k = 1 ;x.clear();dfs(1) ;int ans = 0 ;int m = 15 ;while(m --){int res = 0 ;for(int i = a[m-1] ; i <= a[m] - 1 && i <= 4 * n; i ++){if(x[i]) res ++ ;}ans = max(ans,res) ;}cout << ans << endl;}
}

二叉树的其他遍历方式详见
添加链接描述

F-合法入栈顺序

题意:一个入栈序列是{1,2,3}的合法出栈序列有{3,2,1},{1,2,3}等,而{3,1,2}是不合法的.现在有一个长度为n的序列A(保证序列内数字唯一,且1<=A[i]<=n)。他想知道这个序列是不是入栈顺序{1,2,3,…n}的合法出栈序列,如果是输出YES,否则输出NO
思路:首先,要知道栈stack是一种数据结构,插入和删除只在表的一端进行。这一端称为栈顶(Stack Top),另一端则为栈底(Stack Bottom)。堆栈的元素插入称为入栈,元素的删除称为出栈。
图解为

面对任何一个状态, 我们只有两种选择:
把下一个数进栈
把当前栈顶的数出栈(如果栈非空)
要判断当前的序列是否为合法序列
贪心的角度来想,序列的第一个数一定是第一个弹出去的,第二个也是第二个弹出去的,第n个数是第n个弹出来的.所以将1到n在入栈的时候,每插入一个数,就判断当前栈顶元素是不是序列的第一个数,如果是就弹出栈顶,然后继续判断栈顶元素是不是序列的第二个数,如果不是就继续插入,然后一直重复此过程.
如果最后栈为空说明弹完了,是合法序列,否则不是.

#include<bits/stdc++.h>
#define fer(i,a,b) for(int i = a ; i <= b ; i ++)
#define re register int
typedef long long ll ;
using namespace std;
const int N = 110000 ;
int t ;
int n ;
int a[N] ;
int main()
{cin >> t ;while(t--){stack<int> q ;while(q.size()) q.pop() ;cin >> n ;fer(i,1,n) cin >> a[i] ;int k = 1 ;for(int i = 1 ; i <= n ; i ++){q.push(i);while(q.size() && q.top() == a[k]) {k ++ ;q.pop() ;}}if(q.size()) puts("NO");else puts("YES");}return 0 ;
}

G

添加链接描述

buctoj2021年ACM竞赛班训练(四)全题解相关推荐

  1. BUCTOJ2021年ACM竞赛班训练九题解

    BUCTOJ2021年ACM竞赛班训练九题解 问题A 问题B 问题C 问题D 问题E 问题F 问题A 原题链接 A题题解: 首先让我们看看这个题的题目,ummm-好像要找题目,好吧,我们去看看题目在哪 ...

  2. buctoj2021年ACM竞赛班训练(七)题解

    A: 玩游戏 题意:初始有一堆石子共n个,双方轮流行动,每次可以从中取出恰好完全平方数(1.4.9--)个石子,不可以不取石子直接跳过回合.双方都足够聪明,会按最优的方式来游玩,无法行动的人输掉该游戏 ...

  3. 2021年ACM竞赛班训练(六)题解

    2021年ACM竞赛班训练(六)题解 ==Problem A 逆元== 题目描述 输入 输出 题目分析 代码 ==Problem B&C 五一假期前最后一题&女神的考验== 题目描述 ...

  4. BUCT-2021年ACM竞赛班训练(一)2021.3.25-问题 A: 大佬的高级IDLE-题解

    目录 大佬的高级IDLE 题目描述 输入描述 输出描述 示例1 输入 输出 说明 题目分析 解题思路 并查集离散化 AC代码 大佬的高级IDLE 传送门 时间限制:2秒 空间限制:128M 题目描述 ...

  5. 2021年ACM竞赛班训练(十一)2021.5.20-问题 E: 调皮的摩尔-题解

    传送门 Balloon 题目描述 输入描述 输出描述 样例一 输入 输出 说明 提示 题目分析 注意事项 AC代码 Balloon 传送门 时间限制:1秒 空间限制:128M 题目描述 儿童节突然火起 ...

  6. 集合划分讲解-And-2021年ACM竞赛班训练(九)2021.5.20-问题 E: 登上火星-题解

    集合划分 集合划分,把 n n n个数分成 k k k个集合,不能包含空集,所有的划分数量记为斯大林数,用 S ( n , k ) S(n,k) S(n,k)表示. 目前斯大林数没有直接的公式,但是有 ...

  7. BUCT-2021年ACM竞赛班训练(六)2021.4.29-问题 C:女神的考验-题解

    传送门 女神的考验 题目描述 输入描述 输出描述 样例一 输入 输出 题目分析 注意事项 AC代码 女神的考验 传送门 时间限制:1秒 空间限制:128M 题目描述 星空点点,墨日曜淡.世界芳华灼灼, ...

  8. CSDN 编程竞赛二十四期题解

    竞赛总览 CSDN 编程竞赛二十四期:比赛详情 (csdn.net) 本次竞赛感觉打模板的题变少了,而且多了很多可以集思广益的题目,参赛体验很好. 竞赛题解 题目1.计数问题 试计算在区间1到n的所有 ...

  9. 拿下Facebook黑客杯四冠王!与Jeff Dean相提并论...ACM竞赛之神的传奇前半生

    作者 | 陈大鑫.青暮 转载自:AI科技评论 近日,Facebook Hacker Cup(黑客杯)总决赛落下帷幕,最终,现年26岁的白俄罗斯选手Gennady Korotkevich(比赛网名:To ...

  10. ACM如何入门,ACM竞赛需要学习哪些算法?

    #################成绩################## 大一:2017年4月份"玲珑杯"河南工业大学2017年ACM程序设计大赛暨河南高校邀请赛,获得银奖 20 ...

最新文章

  1. POJ3468--A Simple Problem with Integers--线段树/树状数组 改段求段
  2. php协程实现mysql异步_swoole与php协程实现异步非阻塞IO开发
  3. BeetleX.WebFamily文件图片管理集成
  4. 配置java时找不到匹配项,检索项目的父项时出错:找不到与给定名称匹配的资源...
  5. ORACLE分页查询SQL语法——高效的分页
  6. 【Linux】监视CPU、GPU使用情况
  7. PHP获取照片exif信息
  8. 【Maven】1.使用myecplise配置自己的Maven配置,不使用默认的maven
  9. 世界首次发现?包名导致eclipse找不到包含main的类
  10. 创建可扩展性系统-12
  11. 拿R来画画(八):面积图与堆积图
  12. [白话解析] 深入浅出最大熵模型
  13. 模式识别教材书选择填空期末汇总
  14. IDA pro与x64dbg地址对齐
  15. [工作记事] Ubuntu 编译安装PHP以及gd库使得支持jepg
  16. 以优质氘代产品为刃,劈开生物原材料市场壁垒
  17. Centos7 查看 CPU 核数 和 型号 和 主频(亲测有效)
  18. GA/百度统计/Piwik/JYC:网站分析工具的Cookie设置和访次切分规则
  19. 《2020年蓝桥杯C++b组》
  20. 多标签分类的结果评估---macro-average和micro-average介绍

热门文章

  1. kvm虚拟机日常操作命令梳理
  2. matlab中输入数学符号,matlab 数学符号输入
  3. 计算机产生背景和编程语言分类
  4. 怎么才能优雅地向博士导师表达「这周科研没什么进展」?
  5. 数据库中主键、超键、候选键、外键是什么?
  6. 工业镜头的主要参数与选型
  7. Hive实战之Youtube数据集
  8. 如何用计算机控制三相电机,计算机控制 课程设计 三相步进电机控制.docx
  9. mysql分区替换,MySQL交换分区的实例详解
  10. NumPy学习笔记21. IO