参考蓝桥杯官网给出的赛题和官方给出的代码。
蓝桥杯官方讲解视频:https://www.lanqiao.cn/courses/2737
真题文档:https://www.lanqiao.cn/courses/2786/learning/?id=67104
时间:4小时
总分:150分
不想做全套题的可以考虑4,7,9,10题
题1.三角形面积[填空][3分]
1.题目描述
如图1所示。图中的所有小方格面积都是1。
那么,图中的三角形面积应该是多少呢?
请填写三角形的面积。不要填写任何多余内容或说明性文字。
2.简要分析
- 矩形面积减去三个三角形面积。(64-36=28)
3.答案
28
题2.立方变自身[填空][5分]
1.题目描述
观察下面的现象,某个数字的立方,按位累加仍然等于自身。
1^3 = 1
8^3 = 512 5+1+2=8
17^3 = 4913 4+9+1+3=17
…
请你计算包括1,8,17在内,符合这个性质的正整数一共有多少个?
请填写该数字,不要填写任何多余的内容或说明性的文字。
2.简要分析
- 题目很简单,不过有点模糊的就是这个正整数的范围。
- 如果硬做的话,我们循环到9999或者99999,看看最后的个数是否稳定就可以了。
- 这里我们可以简单的推理一下,假设这个数字是个三位数,那么100^3=1000000,是个七位数,七位数相加,最大可能是7*9=63,已经小于100了,所有三位数就是不可能的了,我们只需要循环到99即可。
3.实现代码(模拟)
public class _02立方变自身 {
private static int ans;
public static void main(String[] args) {
for (int i = 1; i <99; i++) {
int i1 = i * i * i;
int sum=sum(i1);
if (sum==i){
System.out.println(i+" "+i1);
ans++;
}
}
System.out.println(ans);
}
private static int sum(int x) {
String s=String.valueOf(x);
int sum=0;
for (int i = 0; i < s.length(); i++) {
sum+=s.charAt(i)-'0';
}
return sum;
}
}//6
4.答案
6
题3.三羊献瑞[填空][9分]
1.题目描述
观察下面的加法算式:
祥 瑞 生 辉
+ 三 羊 献 瑞
-------------------
三 羊 生 瑞 气
其中,相同的汉字代表相同的数字,不同的汉字代表不同的数字。
请你填写“三羊献瑞”所代表的4位数字(答案唯一),不要填写任何多余内容。
2.简要分析
- 初步的看一下这个算式,可以基本确定,
三
就是1
(两位数加法进位),那么祥
就是9
,羊
就是0
,后面似乎无法确定下来,不过也可以得到一些大小关系,无妨用字母替代:
a b c d
+ e f g b
-------------------
e f c b i
e=1,a=9,f=0,c=b+1,c+g>10
- 我们可以枚举剩下的数字
b
,d
,g
,i
。这四个数字不相等,且不可能是已经确定了的0
,1
,9
。
3.实现代码(枚举)
public class _03三羊献瑞 {
public static void main(String[] args) {
for (int b = 2; b < 9; ++b) {
for (int d = 2; d < 9; ++d) {
if (b == d) continue;
for (int g = 2; g < 9; ++g) {
if (g == b || g == d) continue;
int c = b + 1;
if (c == b || c == d || c == g) continue;
if (c + g <= 10) continue;
/*
a b c d
+ e f g b
-------------------
e f c b i
e=1,a=9,f=0,c=b+1,c+g>10
*/
int sum = 9000 + b * 100 + c * 10 + d + 1000 + g * 10 + b;
for (int i = 2; i < 9; ++i) {
if (i == b || i == d || i == g || i == c) continue;
if (sum == (10000 + c * 100 + b * 10 + i)) {
System.out.printf("%2d%d%d%d\n", 9, b, c, d);
System.out.printf("%2d%d%d%d\n", 1, 0, g, b);
System.out.printf("---------\n");
System.out.printf("%d\n", sum);
}
}
}
}
}
}
}
4.答案
1085
题4.循环节长度[代码填空][11分]
1.题目描述
两个整数做除法,有时会产生循环小数,其循环部分称为:循环节。
比如,11/13=6=>0.846153846153… 其循环节为[846153] 共有6位。
下面的方法,可以求出循环节的长度。
请仔细阅读代码,并填写划线部分缺少的代码。
public static int f(int n, int m)
{
n = n % m;//11
Vector v = new Vector();
for(;;)
{
v.add(n);//11 6
n *= 10;//110 60
n = n % m;//6
if(n==0) return 0;
if(v.indexOf(n)>=0) _________________________________ ; //填空
}
}
注意,只能填写缺少的部分,不要重复抄写已有代码。不要填写任何多余的文字。
2.简要分析
-
分析这段代码,先以一种大概猜测的形式去做,经过一些运算,将一些数字加入向量中,然后如果发现n已经在v里面有了,应该执行一个什么样的操作。大胆猜测,肯定就是这个时候找到了循环节,那么这个向量里面装的应该就是小数部分,循环节的长度应该等于此时v的长度减去第一次出现n的位置(下标)。
-
当然上面只是我们的一种猜测,接下来仔细分析一下代码。用11和13模拟一下。
- 首先n=11%13=11。
- 然后创建了一个vector。接下来一直循环。
- 将n放入v,此时的v:
11
- n=110。
- n=110%13=6。
- 将n放入v,此时v:
11,6
。 - n=60。
- n=60%13=8。
- 将n放入v,此时v:
11,6,8
。 ..........
-
通过上面的模拟我们可以发现,题目中的代码实际上是在模拟除的过程,不管它关注的只是余数,v里面存的也是余数,这样我们就可以发现,如果在计算过程中遇到两个一样的于是,因为m是固定的,按照问我们常规的除法计算,这里肯定是存在循环的,中间每一个余数对应的是一位小数,所以循环节的长度就是v的长度减去n第一次在v中出现的位置(下标)。
-
我们第一次的大胆猜测,虽然答案没有错,但其实原理是不对的,哈哈哈。
3.实现代码
public class _04_循环节长度 {
public static int f(int n, int m) {
n = n % m;
Vector v = new Vector();
for (; ; ) {
v.add(n);
n *= 10;
n = n % m;
if (n == 0) return 0;
if (v.indexOf(n) >= 0)
return v.size() - v.indexOf(n); //填空
}
}
public static void main(String[] args) {
System.out.println(f(11, 13));
System.out.println(f(7, 18));
System.out.println(11%13);
}
}
4.答案
return v.size() - v.indexOf(n)
题5.九数组分数[代码填空][15分]
1.题目描述
1,2,3…9 这九个数字组成一个分数,其值恰好为1/3,如何组法?
下面的程序实现了该功能,请填写划线部分缺失的代码。
public class A
{
public static void test(int[] x)
{
int a = x[0]*1000 + x[1]*100 + x[2]*10 + x[3];
int b = x[4]*10000 + x[5]*1000 + x[6]*100 + x[7]*10 + x[8];
if(a*3==b) System.out.println(a + " " + b);
}
public static void f(int[] x, int k)
{
if(k>=x.length){
test(x);
return;
}
for(int i=k; i<x.length; i++){
{int t=x[k]; x[k]=x[i]; x[i]=t;}
f(x,k+1);
_______________________________________ // 填空
}
}
public static void main(String[] args)
{
int[] x = {1,2,3,4,5,6,7,8,9};
f(x,0);
}
}
注意,只能填写缺少的部分,不要重复抄写已有代码。不要填写任何多余的文字。
2.简要分析
- 读完题,发现是一个全排列问题,再看代码,果然是,看空缺的地方,其实就是全排列中恢复两个交换值的地方。
- 需要特别注意的是,上面的交换代码用括号括起来了,里面声明的变量t不能在下面直接使用!
3.实现代码
public class _05九数组分数 {
public static void test(int[] x)
{
int a = x[0]*1000 + x[1]*100 + x[2]*10 + x[3];
int b = x[4]*10000 + x[5]*1000 + x[6]*100 + x[7]*10 + x[8];
if(a*3==b) System.out.println(a + " " + b);
}
public static void f(int[] x, int k)
{
if(k>=x.length){
test(x);
return;
}
for(int i=k; i<x.length; i++){
{int t=x[k]; x[k]=x[i]; x[i]=t;}
f(x,k+1);
{int t=x[k]; x[k]=x[i]; x[i]=t;} // 填空
}
}
public static void main(String[] args)
{
int[] x = {1,2,3,4,5,6,7,8,9};
f(x,0);
}
}
4.答案
{int t=x[k]; x[k]=x[i]; x[i]=t;}
题6.加法变乘法[填空][17分]
1.题目描述
我们都知道:1+2+3+ … + 49 = 1225 现在要求你把其中两个不相邻的加号变成乘号,使得结果为2015
比如: 1+2+3+…+1011+12+…+2728+29+…+49 = 2015 就是符合要求的答案。
请你寻找另外一个可能的答案,并把位置靠前的那个乘号左边的数字提交(对于示例,就是提交10)。
注意:需要你提交的是一个整数,不要填写任何多余的内容。
2.简要分析
- 双层循环暴力枚举两个乘号的位置即可。
3.实现代码(暴力枚举)
public class _06_加法变乘法 {
public static void main(String[] args) {
for (int i = 1; i <= 46; i++) {
for (int j = i + 2; j <= 48; j++) {
if (i * (i + 1) - (i + i + 1) + j * (j + 1) - (j + j + 1) == 2015 - 1225)
System.out.println(i + " " + j);
}
}
}
}
4.答案
16
题7.牌型种数[填空][21分]
1.题目描述
小明被劫持到X赌城,被迫与其他3人玩牌。
一副扑克牌(去掉大小王牌,共52张),均匀发给4个人,每个人13张。
这时,小明脑子里突然冒出一个问题:
如果不考虑花色,只考虑点数,也不考虑自己得到的牌的先后顺序,自己手里能拿到的初始牌型组合一共有多少种呢?
请填写该整数,不要填写任何多余的内容或说明文字。
2.简要分析
- 其实就是无顺序的全排列问题,也可以理解为DFS的一种应用。
- 直接看代码。
- 二维动态规划解决方法:牌型种数问题–二维动态规划解决(附DFS)
3.实现代码(无顺序全排列)
public class _07_牌型种数 {
private static int ans;
public static void main(String[] args) {
f(0, 0);
System.out.println(ans);
}
private static void f(int k, int cnt) {
if (k > 13 || cnt > 13) return;
if (k == 13 && cnt == 13) {
ans++;
return;
}
for (int i = 0; i < 5; i++) {
f(k + 1, cnt + i);
}
}
}
4.答案
3598180
题8.饮料换购[13分]
1.题目描述
乐羊羊饮料厂正在举办一次促销优惠活动。乐羊羊C型饮料,凭3个瓶盖可以再换一瓶C型饮料,并且可以一直循环下去,但不允许赊账。
请你计算一下,如果小明不浪费瓶盖,尽量地参加活动,那么,对于他初始买入的n瓶饮料,最后他一共能得到多少瓶饮料。
输入:一个整数n,表示开始购买的饮料数量(0<n<10000)
输出:一个整数,表示实际得到的饮料数
例如:
用户输入:
100
程序应该输出:
149
用户输入:
101
程序应该输出:
151
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
2.简要分析
- 简单模拟一下换饮料的过程即可。
- 初始总共得到的饮料数为n。
- 当n>=3时,每换一次饮料相当于n-=2,总共得到的饮料数+1。
3.实现代码(简单模拟)
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int ans = n;
while (n >= 3) {
n -= 2;
ans += 1;
}
System.out.println(ans);
}
}
题9.垒骰子[25分]
1.题目描述
赌圣atm晚年迷恋上了垒骰子,就是把骰子一个垒在另一个上边,不能歪歪扭扭,要垒成方柱体。
经过长期观察,atm 发现了稳定骰子的奥秘:有些数字的面贴着会互相排斥!
我们先来规范一下骰子:1 的对面是 4,2 的对面是 5,3 的对面是 6。
假设有 m 组互斥现象,每组中的那两个数字的面紧贴在一起,骰子就不能稳定的垒起来。 atm想计算一下有多少种不同的可能的垒骰子方式。
两种垒骰子方式相同,当且仅当这两种方式中对应高度的骰子的对应数字的朝向都相同。
由于方案数可能过多,请输出模 10^9 + 7 的结果。
不要小看了 atm 的骰子数量哦~
「输入格式」
第一行两个整数 n m
n表示骰子数目
接下来 m 行,每行两个整数 a b ,表示 a 和 b 不能紧贴在一起。
「输出格式」
一行一个数,表示答案模 10^9 + 7 的结果。
「样例输入」
2 1
1 2
「样例输出」
544
「数据范围」
对于 30% 的数据:n <= 5
对于 60% 的数据:n <= 100
对于 100% 的数据:0 < n <= 10^9, m <= 36
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 2000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
2.简要分析
-
题目很好理解,就是n个骰子,在满足对应的面不贴在一起的时候,总共有多少种可能性。大概方法分析一下:
- 首先,很好理解的就是,骰子的边上四个面都可以旋转,所以在垒好n个骰子之后,因为旋转侧面,总的可能数会是4的n次方,这样只要计算不需要考虑旋转情况下垒好n个骰子的可能数m,最后的结果就是4的m次方。不过由于这个数或很大,所以最好使用快速幂的方法去计算这个结果。
- 我们可以拿例子来简单的看一下,两个骰子不考虑四边旋转的时候,可能数是6*6-2=34(有两个会冲突),然后再乘上2的四次方16,最后的结果就是544.
- 对于每一个骰子,都有6个面,每一个面都可以做为一个朝上的面与其他面接触(需要排除产生冲突的情况)。所以,用递归或者迭代的方式,都是可以做出来的。但是数据的规模达到了10的9次方,这两种方法肯定都会超时。
- 这题的标准思路是矩阵的方法。
-
下面是三种实现方式,只有矩阵快速幂的方式是可以完全通过测试案例的。
3.实现代码1(递归)(会超时)
- 递归实现的方式很好理解,从第n个骰子开始,向下递归,如果冲突就不计算,出口是cnt=0,也就是递归到第一个骰子,此时返回1.
- 但是多达10^9的递归,毫无疑问会超时。
- 递归方面,也没得好的优化办法。
public class _2015_b9_1 {
static int op[] = new int[7];
static long conflict[][] = new long[7][7];
private static int n;
private static int m;
private static final long MOD = 1000000007;
//初始化骰子的对立面
static void init() {
op[1] = 4;
op[4] = 1;
op[2] = 5;
op[5] = 2;
op[3] = 6;
op[6] = 3;
}
public static void main(String[] args) {
init();
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
//初始化冲突矩阵 - 1代表没有冲突
for (int i = 0; i <=6; i++) {
for (int j = 0; j<=6; j++) {
conflict[i][j]=1;
}
}
//建立冲突矩阵
for (int i = 0; i < m; i++) {
int a = sc.nextInt();
int b = sc.nextInt();
//0代表有冲突的面
conflict[op[a]][b] = 0;
conflict[op[b]][a] = 0;
}
long ans=0;
for(int i=1;i<=6;i++){
ans=(ans+f(i,n-1))%MOD;
}
System.out.println(ans * power(4, n) % MOD);
}
private static long f(int up,int cnt){
if(cnt==0){
return 1;
}
long ans=0;
for(int i=1;i<=6;i++){
if(conflict[op[up]][i]==0) continue;
ans+=f(i,cnt-1);
}
return ans;
}
//快速幂
private static long power(long i, int n) {
long ans = 1;
while (n != 0) {
if ((n & 1) == 1) ans = (ans * i) % MOD;
i = i * i % MOD;
n >>= 1;
}
return ans;
}
}
4.实现代码2(动态规划)(会超时)
- dp的方式需要能找出合适的递推关系。
- 通过递归的思路,我们可以得出如下的递推关系式:
- 假设
dp[i][j]
表示第i
层,限定朝上的数字为j
的方案数。 - 那么我们可以得到递推关系式子:
dp[i][j]=(求和x从1到6)dp[i-1][x] | x与op[j]不冲突
。 - 因为每一层都只和上一层有关系,所以dp的第一维的长度可以缩小,能够减少大量空间,只需
dp[2][7]
即可。 - 这个dp还是比较好理解的。
- 但是时间复杂度达到O(36n),还是会超时。
public class _2015_b9_2 {
static int op[] = new int[7];
static long conflict[][] = new long[7][7];
static long dp[][]=new long [2][7];
private static int n;
private static int m;
private static final long MOD = 1000000007;
//初始化骰子的对立面
static void init() {
op[1] = 4;
op[4] = 1;
op[2] = 5;
op[5] = 2;
op[3] = 6;
op[6] = 3;
}
public static void main(String[] args) {
init();
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
//初始化冲突矩阵 - 1代表没有冲突
for (int i = 0; i <=6; i++) {
for (int j = 0; j<=6; j++) {
conflict[i][j]=1;
}
}
//建立冲突矩阵
for (int i = 0; i < m; i++) {
int a = sc.nextInt();
int b = sc.nextInt();
//0代表有冲突的面
conflict[op[a]][b] = 0;
conflict[op[b]][a] = 0;
}
for(int i=1;i<=6;i++){
dp[0][i]=1;
}
int cur=0;
//最外层循环-迭代的层数
for(int floor=2;floor<=n;floor++){
//滚动数组
cur=1-cur;
//尝试将六面作为朝上面
for(int j=1;j<=6;j++){
dp[cur][j]=0;
//累加不冲突的面
for(int i=1;i<=6;i++){
//有冲突
if(conflict[op[j]][i]==0) continue;
dp[cur][j]=(dp[cur][j]+dp[1-cur][i])%MOD;
}
}
}
long ans=0;
for(int k=1;k<=6;k++){
ans=(ans+dp[cur][k])%MOD;
}
System.out.println(ans * power(4, n) % MOD);
}
//快速幂
private static long power(long i, int n) {
long ans = 1;
while (n != 0) {
if ((n & 1) == 1) ans = (ans * i) % MOD;
i = i * i % MOD;
n >>= 1;
}
return ans;
}
}
5.实现代码3(矩阵快速幂)
- 用矩阵实现的关键在于要能发现:(冲突矩阵的n-1次方)*(6行全1列向量)=第一个骰子每一个面可能种数构成的矩阵。
- 具体如何发现的,可以根据dp关系推导递推矩阵,也可以从头开始尝试。
- 矩阵的n-1次方可以使用矩阵快速幂的方式实现,这样时间复杂度就可以降下来了。
public class Main {
static int op[] = new int[7];
private static int n;
private static int m;
private static final long MOD = 1000000007;
//初始化骰子的对立面
static void init() {
op[1] = 4;
op[4] = 1;
op[2] = 5;
op[5] = 2;
op[3] = 6;
op[6] = 3;
}
public static void main(String[] args) {
init();
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
long conflict[][] = new long[6][6];
//初始化冲突矩阵 - 1代表没有冲突
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 6; j++) {
conflict[i][j]=1;
}
}
//建立冲突矩阵
for (int i = 0; i < m; i++) {
int a = sc.nextInt();
int b = sc.nextInt();
//0代表有冲突的面
conflict[op[a] - 1][b - 1] = 0;
conflict[op[b] - 1][a - 1] = 0;
}
// 求冲突矩阵的n-1次方
long[][] mPow_n_1 = mPow(conflict, n - 1);
//累加矩阵的每个元素
long ans = 0;
//枚举第一个骰子和第二个骰子面相邻的所有可能
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 6; j++) {
ans = (ans + mPow_n_1[i][j]) % MOD;
}
}
//ans*4^n
System.out.println(ans * power(4, n) % MOD);
}
//快速幂
private static long power(long i, int n) {
long ans = 1;
while (n != 0) {
if ((n & 1) == 1) ans = (ans * i) % MOD;
i = i * i % MOD;
n >>= 1;
}
return ans;
}
/*矩阵的快速幂*/
private static long[][] mPow(long[][] conflict, int n) {
long[][] e = new long[6][6];
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 6; j++) {
if (i == j) e[i][j] = 1;
else e[i][j] = 0;
}
}
while (n != 0) {
if ((n & 1) == 1) {
e = mMul(e, conflict);
}
conflict = mMul(conflict, conflict);
n >>= 1;
}
return e;
}
//矩阵乘法
private static long[][] mMul(long[][] a, long[][] b) {
long[][] ans = new long[6][6];
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 6; j++) {
for (int k = 0; k < 6; k++) {
ans[i][j] = (ans[i][j] + a[i][k] * b[k][j]) % MOD;
}
}
}
return ans;
}
}
题10.生命之树[31分]
1.题目描述
在X森林里,上帝创建了生命之树。
他给每棵树的每个节点(叶子也称为一个节点)上,都标了一个整数,代表这个点的和谐值。
上帝要在这棵树内选出一个非空节点集S,使得对于S中的任意两个点a,b,都存在一个点列 {a, v1, v2, …, vk, b} 使得这个点列中的每个点都是S里面的元素,且序列中相邻两个点间有一条边相连。
在这个前提下,上帝要使得S中的点所对应的整数的和尽量大。
这个最大的和就是上帝给生命之树的评分。
经过atm的努力,他已经知道了上帝给每棵树上每个节点上的整数。但是由于 atm 不擅长计算,他不知道怎样有效的求评分。他需要你为他写一个程序来计算一棵树的分数。
「输入格式」
第一行一个整数 n 表示这棵树有 n 个节点。
第二行 n 个整数,依次表示每个节点的评分。
接下来 n-1 行,每行 2 个整数 u, v,表示存在一条 u 到 v 的边。由于这是一棵树,所以是不存在环的。
「输出格式」
输出一行一个数,表示上帝给这棵树的分数。
「样例输入」
5
1 -2 -3 4 5
4 2
3 1
1 2
2 5
「样例输出」
8
「数据范围」
对于 30% 的数据,n <= 10
对于 100% 的数据,0 < n <= 10^5, 每个节点的评分的绝对值不超过 10^6 。
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 3000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
2.简要分析
- 由题意可以知道,这是一棵无根树。
- 对于无根树,我们可以将每一个节点做为根节点去计算最大的值,最后取所有可能里面的最大值。
- 具体实现见代码。
3.实现代码
public class Main {
private static int n;
//存储所有节点的权值
private static long[] w;
//
private static List<Integer>[] g;
private static long ans ;
public static void main(String[] args) throws FileNotFoundException {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
w = new long[n + 1];
g = new ArrayList[n + 1];
initG();
for (int i = 1; i <= n; i++) {
w[i] = sc.nextLong();
}
for (int i = 0; i < n - 1; i++) {
int a = sc.nextInt();
int b = sc.nextInt();
g[a].add(b);
g[b].add(a);
}
dfs(1, 0);
System.out.println(ans);
}
/**
* root做为根所代表的子树有一个最大权和,将其存储在w[root]中
* @param root
* @param fa
*/
private static void dfs(int root, int fa) {
//遍历每一个相连的节点
for (int i = 0; i < g[root].size(); i++) {
Integer child = g[root].get(i);
if (child == fa) continue;
//递归计算
dfs(child, root);
if (w[child] > 0)
w[root] += w[child];
}
//不断更新最大值
if (w[root] > ans) ans = w[root];
}
//初始化二维集合g
private static void initG() {
for (int i = 0; i < n + 1; i++) {
g[i] = new ArrayList<Integer>();
}
}
}
总结
-
做一遍下来头晕了~~~
-
1-8题难度不大,最后两题还是有一定难度的。
-
梳理一下考点:
- 1.暴力枚举。
- 2.代码分析。
- 3.无序的全排列。
- 4.经典全排列。
- 5.过程模拟。
- 6.矩阵快速幂。
- 7.无根树的转换。
-
矩阵快速幂和无根树的转换是这套题目的重点了。
ATFWUS Writing 2021-1-23