黄钻9
A
题意:
牛牛从牛毕那里拿了一根长度为n的白木板,木板被等分成了n段(没有被切割,只是虚拟划分成了n段),其中有些段被牛毕用颜料染成了黑色。
牛牛非常不喜欢黑色,它找来了一桶清洗剂决定对木板进行清洗,但是牛牛发现自己的清洗剂最多只能清洗m段。
清洗完后,牛牛会把木板锯成纯色的几段。例如假设木板是 (黑黑黑白白白白黑黑黑 ),就会被锯成(黑黑黑)(白白白白)(黑黑黑)三段。
牛牛想知道,它足够聪明地清洗木板,能获得的纯白色木板的最大长度是多少。
输入:
给定n,m两个整数
和一个长度为n的数组a,为1表示白色,为0表示黑色
输出:
一行一个数字表示能获得的纯白色木板的最大长度是多少
思路:数组sum求前i段中黑色的段数,然后遍历一遍sum,找到黑色段数小于m且区间长度最大的区间。
代码:
class Solution {
public:
/**
*
* @param n int整型
* @param m int整型
* @param a int整型vector
* @return int整型
*/
int sum[1000005];//如上所述
int solve(int n, int m, vector<int>& a) {
// write code here
for(int i=0;i<a.size();i++){
sum[i+1]=sum[i];
if(a[i]==0)sum[i+1]++;
}
int ans=0,l=0,r=1;
for(int i=1;i<=n;i++){
while(l<=n&&sum[r]-sum[l]>m)l++;
while(r<=n&&sum[r]-sum[l]<=m)r++;
ans=max(ans,r-1-l);
}
return ans;
}
};B
题目
给定一棵有n个结点的二叉树的先序遍历与后序遍历序列,求其中序遍历序列。
若某节点只有一个子结点,则此处将其看作左儿子结点.
思路:看到题目就想直接将这棵二叉树构造出来,然后想半天没想起数据结构课咋讲的。不太明白的话还是直接复习数据结构吧。
代码:
class Solution {
public:
/**
* 返回所求中序序列
* @param n int整型 二叉树节点数量
* @param pre int整型vector 前序序列
* @param suf int整型vector 后序序列
* @return int整型vector
*/
vector<int>v;
int l[100005],r[100005],fa[100005];
map<int,int>mp;
void dfs(int u)
{
if(u==0)return;
dfs(l[u]);
v.push_back(u);
dfs(r[u]);
}
vector<int> solve(int n, vector<int>& pre, vector<int>& suf) {
// write code here
for(int i=0;i<suf.size();i++)mp[suf[i]]=i;
fa[0]=0;
//根据序列构造树
for(int i=0;i<pre.size()-1;i++){
int u=pre[i],v=pre[i+1];
if(mp[v]<mp[u]){
l[u]=v;
fa[v]=u;
}else{
while(mp[v]>mp[u])u=fa[u];
r[u]=v;
fa[v]=u;
}
}
//再跑一遍树,确定中序序列
dfs(pre[0]);
return v;
}
};C
题意:
游戏是在一个N*N的网格图中进行的,图中的网格分为四种类型,0表示空地可以通过,1表示墙壁无法通过,2表示不仅可以通过,还可以在该格放置一个传送门,3表示有且仅有的唯一的固定传送门。
思路:看起来就是个模拟,实际上还是个模拟。直接暴力搜到达该点的最小步数,然后同时找到最近的2放置传送门用来更新最远的3(直接一步传送)。需要注意的是要从(0,0)出发搜一遍,然后从(N-1,N-1)出发搜一遍,看样例就知道两个起始点算出来的答案不一样,取决于2和3怎么放。
代码:
class Solution {
public:
/**
* 返回最终要输出的答案
* @param N int整型 表示地图的大小
* @param a int整型二维数组 地图的描述
* @param aRowLen int a数组行数
* @param aColLen int* a数组列数
* @return int整型
*/
int vis[550][550],x=0,y=0,temp,temp1,ans;
void dis(int N,int** a,int sx,int sy)//从(sx,sy)出发
{
queue<pair<int,int>>q;
q.push(make_pair(sx,sy));
memset(vis,0x3f3f3f3f,sizeof(vis));
temp=0x3f3f3f3,temp1=0x3f3f3f3f;
vis[sx][sy]=0;
while(!q.empty()){
x=q.front().first,y=q.front().second;
q.pop();
if(a[x][y]==3&&temp+1<vis[x][y])vis[x][y]=temp+1;
else if(a[x][y]==2&&vis[x][y]<temp)temp=vis[x][y];//因为最近的2一般出现在最远的3前面,如果不在,那也不用更新了
//上下左右
if(x-1>=0&&a[x-1][y]!=1&&vis[x][y]+1<vis[x-1][y]){
q.push(make_pair(x-1,y));
vis[x-1][y]=vis[x][y]+1;
}
if(y-1>=0&&a[x][y-1]!=1&&vis[x][y]+1<vis[x][y-1]){
q.push(make_pair(x,y-1));
vis[x][y-1]=vis[x][y]+1;
}
if(x+1<N&&a[x+1][y]!=1&&vis[x][y]+1<vis[x+1][y]){
q.push(make_pair(x+1,y));
vis[x+1][y]=vis[x][y]+1;
}
if(y+1<N&&a[x][y+1]!=1&&vis[x][y]+1<vis[x][y+1]){
q.push(make_pair(x,y+1));
vis[x][y+1]=vis[x][y]+1;
}
}
}
int solve(int N, int** a, int aRowLen, int* aColLen) {
// write code here
dis(N,a,0,0);
ans=vis[N-1][N-1];
dis(N,a,N-1,N-1);
ans=min(ans,vis[0][0]);
return ans;
}
};


京公网安备 11010502036488号