小红书2020校招算法题(三)

一、笔记草稿

题目描述
薯队长写了一篇笔记草稿,请你帮忙输出最后内容。

  1. 输入字符包括,"(" , “)” 和 "<"和其他字符。
  2. 其他字符表示笔记内容。
  3. ()之间表示注释内容,任何字符都无效。 括号保证成对出现。
  4. "<“表示退格, 删去前面一个笔记内容字符。括号不受”<"影响 。
    Input:一行字符串。长度<=10000.
    Output:一行字符串,表示最终的笔记内容。

示例
输入

Corona(Trump)USA<<<Virus

输出

CoronaVirus

分析:
这题考察字符串基本知识,如字符串输入输出、特殊字符处理等,难度应该属于Easy
解题思路:
首先定义两个字符串变量,一个用来读取输入字符串,一个用来储存输出字符串(res)
遍历字符串,对每一个字符做if else判断,因为’(’、’)‘成出现,可以对’(’、’)‘其中一个处理,那么可分为三种情况:
  (1)字符 ==’(’ 时,设置标记值,继续遍历,直到遇到‘)’时跳出循环;
  (2)字符 ==‘<’ 时,如果res不为空,pop掉一个
  (3)字符 == 正常字符时,不断向res中push就完事了。

C++代码实现

#include<iostream>
#include<string>
using namespace std;
int main(){
    string strs;
	getline(cin,strs); //从缓冲区读取一行字符串,也可用: cin>>strs;表示
	string res;
    int n=0;
	//遍历strs字符串对 "(" 、"<"和字符分别处理
	for(int i=0;i<strs.size();i++){
		if(strs[i] == '(' ){  
			i++;
            n++;
            while(i<strs.size() && n!=0){
                if(strs[i] == '(')
                    n++;
                if(strs[i] == ')')
                    n--;
                if(n==0)  //直到括号内字符全部遍历完成,才跳出循环
                        break;
                i++;
            }   
		}
		else if(strs[i] == '<'){
            if(!res.empty())
                res.pop_back();
        }
		else{
			res.push_back(strs[i]);
		}
	}
    cout<<res<<endl;  //输出目标字符串即可
    return 0;
}

二、笔记精选

题目描述
薯队长写了n篇笔记,编号从1~n,每篇笔记都获得了不少点赞数。
薯队长想从中选出一些笔记,作一个精选集合。挑选的时候有两个规则:

  1. 不能出现连续编号的笔记。
  2. 点赞总数最多

如果满足1,2条件有多种方案,挑选笔记总数最少的那种。

Input:两行,第一行数字n,表示文章数;第二行数组nums,表示每篇文章的点赞数。
Output:满足条件的点赞总数和选取的文章数,中间用空格分开

示例
输入

4
1 2 3 4

输出

4 2

分析:这题考察的是动态规划知识,由于需要返回选择的文章数,所以需要另外使用数组,在存储dp[i]时同时记录选择次数!难度属于dp中的Easy

解题思路:
初始化两个vector< int >数组:dp,dpNum,
(1)dp[i]表示从0-i满足条件的笔记点赞总数
(2)dpNum表示dp[i]中选取的笔记数
题目类似于dp经典问题:打家劫舍。很容易可以得到状态转移方程:
d p [ i ] = m a x ( d p [ i + 1 ] , d p [ i + 2 ] + n u m s [ i ] ) dp[i] = max(dp[i+1], dp[i+2]+nums[i]) dp[i]=max(dp[i+1],dp[i+2]+nums[i])

C++代码实现

#include<vector>
#include<iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    vector<int> v;
    for (int i = 0; i < n; i++) {  //读入一个整形数组
        int tp;
        cin >> tp;
        v.push_back(tp);
    }
    vector<int> dp(n), dpnum(n);
    dp[0] = v[0];
    dp[1] = max(v[0],v[1]); //初始化边界值
    dpnum[0] = 1;
    dpnum[1] = 1;
    for (int i = 2; i < n; i++) { 
        if ((v[i] + dp[i - 2]) > dp[i - 1]) {  //选用了v[i],所以篇数+1
            dp[i] = v[i] + dp[i - 2];
            dpnum[i] = 1+ dpnum[i - 2];
        }
        else {  //没有选用,所以篇数不变,为前一个dpnum[i - 1]
            dp[i] = dp[i - 1];
            dpnum[i] = dpnum[i - 1];
        }
    }
    cout << dp[n-1]<<' '<< dpnum[n - 1]; //输出最多点赞数和篇数
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值