蓝桥杯国赛——2018——Java——B

1:求三角形面积:

方法很多,我当时直接求了两个向量的外积

还可以海伦公式,余弦定理求角然后s=(a*b*sinA)/2

2:求最大的a,满足a=b*c其中String(a)包含1-9各一个,(String(b)+String(c))包含1-9各一个[String()指代String.valueOf()]

3:代码填空求1234的全排列!!

显然他是在dfs,dfs在同一位置向下一个状态转换的状态应是相同的,只需要逆着dfs操作上面的操作进行就好了

4:判断矩形

t组数据,n*m的矩阵,矩阵然后给出了。

每个格子只可能是0-9的数字且每个数字代表的矩形【t矩形意味着这个矩形内只有数字t】只有一个。

例如

3 4

1 1 1 1

1 2 2 1

1 1 1 1 

输出 NO

3 4

1 1 2 2 

3 3 4 4

5 5 6 6

输出 YES

3 4

1 1 2 2 

3 3 4 4 

1 1 1 1 

输出 NO

这样我们想到了每种数字如果构成矩形,那么这个矩形再每一行中的开始结尾必相同,如果不是第一行,其上一行首位必然相同

自古简单题无代码

4:版本都有直接祖先一个,然后1是最早的版本,即根节点。

给出  n q代表关系数和查询数

l 是 r 的直接祖先

查询

l 是否是 r 的祖先

典型的LCA(最近一种搞乱七八糟的都不会裸写LCA了,我真tm菜,知道是LCA还是只能写并查集~~~)。

附上C++LCA模板,板子题没必要写题解。

#include <iostream>  
#include <cstdio>  
#include <cstring>  
#define MAX 40010  
  
using namespace std;  
  
struct node  
{  
    int e,next,value;  
}a[3*MAX],b[3*MAX];  
int root[MAX],ans,root1[MAX],ans1;  
int parent[MAX],ancestor[MAX],dis[MAX];  
int vist[MAX],n,m;  
  
void add(int s,int e,int value)  
{  
    a[++ans].e=e;  
    a[ans].value=value;  
    a[ans].next=root[s];  
    root[s]=ans;  
}  
void add1(int s,int e)  
{  
    b[++ans1].e=e;  
    b[ans1].next=root1[s];  
    root1[s]=ans1;  
}  
int find(int x)              //并查集  
{  
    if(x!=parent[x])  
    {  
        parent[x]=find(parent[x]);  
    }  
    return parent[x];  
}  
void tarjan_lca(int s)  
{  
    vist[s]=1;  
    for(int i=root[s]; i!=-1; i=a[i].next)   //以s为根节点进行DFS  
    {  
        int e=a[i].e;  
        if(!vist[e])   
        {  
            dis[e]=dis[s]+a[i].value;  
            tarjan_lca(e);  
            parent[e]=s;            //将根节点以后的子节点连接到根节点  
        }  
    }  
    for(int i=root1[s]; i!=-1; i=b[i].next)         
    {  
        int e=b[i].e;  
        if(vist[e])                          //如果询问(s,e)已经找到就进行更新  
        {  
            b[i].value=dis[s]+dis[e]-2*dis[find(e)];  
            b[i^1].value=b[i].value;  
        }  
    }  
}  

6:不知道正解是啥,反正我觉得结构体排序可以过

一个游戏:

有两个相互关联的值 d=log2(A)=log3(B),这个关系始终成立

有两种药剂 X Y分别可以增加A B值

X 有 x个,Y有y个,给出嗑药顺序,0为A,1为B

第一行 给出 x y

第二行 x个 X 值,代表这种药的的功效:使用后A+=Xi,而改变A,B和d的值

第三行 y个 Y 值,代表这种药的的功效:使用后B+=Yi,而改变A,B和d的值

第四行,一个数字串,代表嗑药顺序

求要d最大的嗑药方式

可以肯定,先磕比较大的药对影响更大,因为对数增长率越来越小

f`(x)=d(loga(x))/d(x)=1/x(lna),a=2||a=3时显然f`(x)递减,故增长慢

如果有两种情况增加的量相同,按字典序小的输出

什么时候可能相同呢?

因为连续增加A的值,总增加量与顺序无关,最终A的值是一样的。B也要同样的规律,也就是说:

当连续取A时,前k大的A要按字典序排列,B也是这样的所以

设置一个继承了Comparable<>的类,按他们增加的值排序

再给这个类写一个Comparator<>类,按他们再输入时的顺序排序

按如上方法排好,分A,B输出即可。

思路给出,不确定是不是正解,暂不给出代码。

猜你喜欢

转载自blog.csdn.net/qq_41104612/article/details/80466766