牛客练习记录第五周

第一题:链接:https://www.nowcoder.com/questionTerminal/824af5cb05794606b56657bb3fa91f49

编程题]善变的同伴

  • 热度指数:601 时间限制:1秒 空间限制:65536K
  • 算法知识视频讲解

又到了吃午饭的时间,你和你的同伴刚刚研发出了最新的GSS-483型自动打饭机器人,现在你们正在对机器人进行功能测试。

为了简化问题,我们假设午饭一共有N个菜,对于第i个菜,你和你的同伴对其定义了一个好吃程度(或难吃程度,如果是负数的话……)A[i],

由于一些技(经)术(费)限制,机器人一次只能接受一个指令:两个数L, R——表示机器人将会去打第L~R一共R-L+1个菜。

本着不浪费的原则,你们决定机器人打上来的菜,含着泪也要都吃完,于是你们希望机器人打的菜的好吃程度之和最大

然而,你善变的同伴希望对机器人进行多次测试(实际上可能是为了多吃到好吃的菜),他想知道机器人打M次菜能达到的最大的好吃程度之和

当然,打过一次的菜是不能再打的,而且你也可以对机器人输入-1, -1,表示一个菜也不打

 

输入描述:

第一行:N, M

第二行:A[1], A[2], ..., A[N]


 

输出描述:

一个数字S,表示M次打菜的最大好吃程度之和

示例1

输入

7 2
1 2 3 -2 3 -10 3

输出

10

说明

[1 2 3 -2 3] -10 [3]

示例2

输入

7 4
1 2 3 -2 3 -10 3

输出

12

说明

[1 2 3] -2 [3] -10 [3]

第四次给机器人-1, -1的指令

 

备注:

N <= 10^5 = 100000

|A[i]| <= 10^4 = 10000

10%数据M = 1

50%数据M <= 2

80%数据M <= 100

100%数据M <= 10^4 = 10000

解题思路:最大m子段合,可以参考https://blog.csdn.net/winter2121/article/details/72848482

#include
#include
#include
#include
#include
#include 
#include 
#include 
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

vectorss;
int dp[2][100005]={0};
int main()
{
    int N, M,sum,h,  k, count, now; //N表示菜的个数,M表示机器人最多打菜的次数,cout表示菜的总的好吃度,now表示当前这道菜的好吃度
    cin >> N >> M;
       
    count = 0; 
    while (N--) {
        cin >> now;  //输入菜的好吃程度
        if (count>0) {  //总的好吃度为正时
            if (now >= 0)  //好吃度为正,累加好吃度
                count += now;
            else {
                ss.push_back(count);   //好吃度为负,把之前总的好吃度存下来,并更新总的好吃度
                count = now;
            }
        }
          
        else if (count<0) {  //总的好吃度为负数时
            if (now >= 0) {
                    ss.push_back(count);  //当前好吃度为正,把之前总的好吃度存下来,并更新总的好吃度
                count = now;
            }
            else
                count += now;   //好吃度为负,累加好吃度
        }
          
        else
            count += now;   //总的好吃度为0时,累加好吃度
    }
      
    if (count>0)   //完成数据输入后,总的好吃度如果为正,那么存下来
    {
        ss.push_back(count);
    }
  
    sum = 0;
    N = ss.size()+1;
    count = 0;
    //可操作次数大于存储下来的总好吃值个数,直接把正的都取出来累加就是最终的总的好吃度
    if(N<=M){
        for (int j = 0; j < N; j++){
            if(ss[j]>0)
                count+=ss[j];
        }
        return 0;
    }
      
    //可操作次数小于存储下来的总的好吃值的个数,转换为二维dp
    else{
        for (int i = 1; i <= M; i++) {
            sum = 0;
            k=i&1;
            h=(i-1)&1;
            //dp[k][0] = 0;
            for (int j = 1; j < N; j++) {
                sum = max(sum, dp[h][j - 1]);
                dp[k][j] = max(sum , dp[k][j - 1]) + ss[j-1];
            }
        }
        for(int i=M;i

第二题:

题目描述

 

通过键盘输入一串小写字母(a~z)组成的字符串。

请编写一个字符串归一化程序,统计字符串中相同字符出现的次数,并按字典序输出字符及其出现次数。

例如字符串"babcc"归一化后为"a1b2c2"

 

 

 

输入描述:

每个测试用例每行为一个字符串,以'\n'结尾,例如cccddecca

输出描述:

输出压缩后的字符串ac5d2e

示例1

输入

复制

dabcab

输出

复制

a2b2c1d1

解题思路:直接使用map存储即可,可以不用排序。

#include
#include
#include
#include
#include
#include 
#include 
#include 
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;


int main()
{
	int n,m;
	string str;
	cin>>str;
	map letter;
	for(int i=0;i::iterator it;
	it=letter.begin();
	for(it;it!=letter.end();it++){
		cout<first<second;
	}
	
}

第三题:https://www.nowcoder.com/practice/0425aa0df74646209d3f56f627298ab2?tpId=98&tqId=32845&rp=1&ru=/ta/2019test&qru=/ta/2019test/question-ranking

题目描述

 

 

月神拿到一个新的数据集,其中每个样本都是一个字符串(长度小于100),样本的的后六位是纯数字,月神需要将所有样本的后六位数字提出来,转换成数字,并排序输出。

 

月神要实现这样一个很简单的功能确没有时间,作为好朋友的你,一定能解决月神的烦恼,对吧。

输入描述:

每个测试用例的第一行是一个正整数M(1<=M<=100),表示数据集的样本数目

接下来输入M行,每行是数据集的一个样本,每个样本均是字符串,且后六位是数字字符。

输出描述:

对每个数据集,输出所有样本的后六位构成的数字排序后的结果(每行输出一个样本的结果)

示例1

输入

复制

4
abc123455
boyxx213456
cba312456
cdwxa654321

输出

复制

123455
213456
312456
654321

解题思路:看到需要排序,想到用set存储,然后把后六位存储即可。

#include
#include
#include
#include
#include
#include 
#include 
#include 
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;


int main()
{
	int n,m;
	string str;
	cin>>n;
	set letter;
	for(int i=0;i>str;
		string temp;
		for(int j=str.size()-6;j::iterator it;
	it=letter.begin();
	for(it;it!=letter.end();it++){
		cout<<*it<

第三题:

题目描述

最大回文子串是被研究得比较多的一个经典问题。最近月神想到了一个变种,对于一个字符串,如果不要求子串连续,那么一个字符串的最大回文子串的最大长度是多少呢。

输入描述:

每个测试用例输入一行字符串(由数字0-9,字母a-z、A-Z构成),字条串长度大于0且不大于1000.

输出描述:

输出该字符串的最长回文子串的长度。(不要求输出最长回文串,并且子串不要求连续)

示例1

输入

复制

adbca

输出

复制

3

解题思路:最长回文子序列

#include
#include
#include
#include
#include
#include 
#include 
#include 
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

int dp[2][1500];
int main()
{
	string str;
	cin>>str;
	int len = str.length();

    memset(dp,0,sizeof(dp));
    int cur = 0;
    for(int i = len - 1; i >= 0; i--)
    {
        cur ^= 1;
        dp[cur][i] = 1;
        for(int j = i + 1; j < len; j++)
        {
            if(str[i] == str[j])
                dp[cur][j] = dp[cur^1][j-1] + 2;
            else
                dp[cur][j] = max(dp[cur][j-1],dp[cur^1][j]);
        }
    }
    cout<

第四题:https://www.nowcoder.com/practice/37aa8a88a72e47f798a14d63bee61d8f?tpId=98&tqId=32851&rp=1&ru=/ta/2019test&qru=/ta/2019test/question-ranking

题目描述

有重量分别为3,5,7公斤的三种货物,和一个载重量为X公斤的箱子(不考虑体积等其它因素,只计算重量)

需要向箱子内装满X公斤的货物,要求使用的货物个数尽可能少(三种货物数量无限)

 

输入描述:

输入箱子载重量X(1 <= X <= 10000),一个整数。

输出描述:

如果无法装满,输出 -1。
如果可以装满,输出使用货物的总个数。

解题思路:多重背包问题

#include
#include
#include
#include
#include
#include 
#include 
#include 
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

int dp[4][10003]={100000};
int main()
{
	int n;
	cin>>n; 
	int b[4]={0,3,5,7};
	
	
	for(int j=0;j<=3;j++){
		for(int i=0;i<=n;i++){
			dp[j][i]=1000000;
		}
	}
	
	dp[0][0]=0;
	for(int j=1;j<=3;j++){
		dp[j][0]=0;
		for(int i=1;i<=n;i++){
			dp[j][i]=dp[j-1][i];
		}
		for(int i=1;i<=n;i++){
			int k=1;
			while((i-k*b[j])>=0){
				dp[j][i]=min(dp[j-1][i-k*b[j]]+k,dp[j][i]);
				k++;
			}
//			cout<

第五题:https://www.nowcoder.com/practice/003482c395bd41c68082f6adc545a600?tpId=98&tqId=32852&rp=1&ru=/ta/2019test&qru=/ta/2019test/question-ranking

题目描述

给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。

("回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。)

具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被计为是不同的子串。

可用C++,Java,C#实现相关代码逻辑

输入描述:

输入一个字符串S 例如“aabcb”(1 <= |S| <= 50), |S|表示字符串S的长度。

输出描述:

符合条件的字符串有"a","a","aa","b","c","b","bcb"

所以答案:7

解题思路:以每一个字符为中间点向两侧扩散,扩散成功则加1,失败则换下一个点

#include
#include
#include
#include
#include
#include 
#include 
#include 
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;


int main()
{
	string str;
	cin>>str;
	int count=str.size();
	for(int i=0;i

第六题:https://www.nowcoder.com/practice/8705437354604a7cb9ba7bf959e42de6?tpId=98&tqId=32855&rp=1&ru=%2Fta%2F2019test&qru=%2Fta%2F2019test%2Fquestion-ranking

题目描述

一个非空整数数组,选择其中的两个位置,使得两个位置之间的数和最大。

如果最大的和为正数,则输出这个数;如果最大的和为负数或0,则输出0

解题思路:累加,小于零就放弃,重新开始,每次累加与最大值比较。

#include
#include
#include
#include
#include
#include 
#include 
#include 
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;


int main(){
	int a[100000]; 
	int length=0;
	for(int i=0;;i++)
	{
		scanf("%d",&a[i]);
		length ++;
		if(getchar()=='\n')
		  break;
	}
	vector b;
	int count=a[0]; 
	for(int i=1;i=0) count+=a[i];
			else{
				b.push_back(count);
				count=a[i];
			}
		}
	}
	b.push_back(count);
	int max=0;
	count=0; 
	for(int i=0;i

第八题:https://www.nowcoder.com/practice/480caa5ffd164ac8b71caaa6d0f4e6db?tpId=98&tqId=32856&rp=1&ru=/ta/2019test&qru=/ta/2019test/question-ranking

题目描述

已知一个字符串数组words,要求寻找其中两个没有重复字符的字符串,使得这两个字符串的长度乘积最大,输出这个最大的乘积。如:

words=["abcd","wxyh","defgh"], 其中不包含重复字符的两个字符串是"abcd"和"wxyh",则输出16

words=["a","aa","aaa","aaaa"], 找不到满足要求的两个字符串,则输出0

解题思路:把输入处理好就可以暴力破解了。

#include
#include
#include
#include
#include
#include 
#include 
#include 
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;


int main(){
	string str;
	vector s;
	getline(cin,str);
	string temp;
	for(int i=0;i='a'){
			temp+=str[i];
		}
		else{
			if(temp.size()){
				s.push_back(temp);
			}
			temp="";
		}
	}
	int maxs=0;
	for(int i=0;i

 

你可能感兴趣的:(算法,C++)