牛客练习记录

21 篇文章 0 订阅

题目描述

给定一个数组序列,需要求选出一个区间,使得该区间是所有区间中经过如下计算的值最大的一个:

区间中的最小数*区间所有数的和

最后程序输出经过计算后的最大值即可,不需要输出具体的区间。如给定序列 [6 2 1]则根据上述公式,可得到所有可以选定各个区间的计算值:

[6] = 6 * 6 = 36;

[2] = 2 * 2 = 4;

[1] = 1 * 1 = 1;

[6,2] = 2 * 8 = 16;

[2,1] = 1 * 3 = 3;

[6, 2, 1] = 1 * 9 = 9;

从上述计算可见选定区间[6],计算值为36, 则程序输出为36。

区间内的所有数字都在[0, 100]的范围内;

地址:https://www.nowcoder.com/practice/70cd4744404a4fbcbffe69e53e1f964c?tpId=90&tqId=30940&rp=9&ru=/ta/2018test&qru=/ta/2018test/question-ranking

本题直接暴力是n平方的复杂度。所以会超时。考虑到区间内所有数字在[0,100]中,但最小值固定,这个区间越大越好,能获得的值就越大,因此,将输入数值以小于这个最小值的数值分成多个区间【1,2,3,4,6,3,1,8,4】如果最小值为2,则区间为【2,3,4,6,3】与【8,4】,最小值为3时,区间就为【3,4,6,3】与【8,4】,计算这个区间值后与最大值相比较,大于最大值就替换。这样计算避免了许多重复计算。

#include <iostream>
#include <vector>

using namespace std ;

int main() {
	int n;
	cin>>n;
	int a[500000];
	for(int i=0;i<n;i++){
		cin>>a[i];
	} 
	int max=0;
	for(int i=1;i<=100;i++){
		int min=101;
		int sum=0;
		for(int j=0;j<n;j++){
			if(a[j]>=i){
				if(a[j]<min) min=a[j];
				sum+=a[j];
			}
			else{
				if(max<min*sum) max=min*sum;
				sum=0;
				min=101;
			}
			if(max<min*sum) max=min*sum;
		}
	} 
	cout<<max;
    return 0;
}
/*


6
6 5 4 3 6 1

3
6 2 1

*/

 

 

第二题:https://www.nowcoder.com/practice/077d8fd660f74a938019b17314ed1707?tpId=90&tqId=30881&rp=6&ru=/ta/2018test&qru=/ta/2018test/question-ranking

题目描述

请从字符串中提取以最后一个[img]开头、以最后一个[\img]结尾的字符串,未找到匹配的字符串返回"null"

输入描述:

可能包含[img][\img]的字符串

输出描述:

截取后的字符串

思路:从后往前遍历,先匹配[\img],再匹配[img],由于是倒序,匹配的字符串需要倒序。如果都匹配到了输出,使用一个字符串记录中间遍历的字符串。

#include<iostream>
#include<algorithm>
#include<string>
#include<math.h>
#include<stdlib.h>
#include <iostream>
#include <vector>
#include <queue>
using namespace std ;
int mins=-100000;
int a[1000][1000];
int n,m;

int main() {	
	string s;
	cin>>s;
	string start="]gmi\\[",end="]gmi[";
	int flag_end=0;
	int flag_start=0;
	string s2;
	for(int i=s.size()-1;i>=0;i--){
		int flag=0;
		if(flag_end==0){
			for(int j=0;j<start.size();j++){
//				cout<<start[j]<<' '<<s[i-j]<<' '<<j<<endl; 
				if(start[j]!=s[i-j]){
					flag=1;
					break;
				}
			}
			if(flag==0){
				flag_end=1;
				s2+=start;
				i=i-start.size()+1;
			}
		}
		else{
			s2+=s[i];
//			cout<<"s2:"<<s2<<' '<<s[i]<<endl;
			for(int j=0;j<end.size();j++){
				if(end[j]!=s[i-j]){
					flag=1;
					break;
				}
			}
			if(flag==0){
				flag_start=1;
				break;
			} 
		}
	} 
	if(flag_end==1&&flag_start==1){
		cout<<"[img";
		for(int i=s2.size()-1;i>=0;i--)
		cout<<s2[i];
	} 
	else cout<<"null";
}
/*


bbb[img]ccc[img]ddd[\img]eee[\img]

*/

 

第三题:https://www.nowcoder.com/practice/e172dbac7d9140e98eef66c9ebbe25f8?tpId=90&tqId=30882&rp=6&ru=/ta/2018test&qru=/ta/2018test/question-ranking

题目描述

请从字符串中找出至少重复一次的子字符串的最大长度

输入描述:

字符串,长度不超过1000

输出描述:

重复子串的长度,不存在输出0

字符串较小,暴力就能过(笑)

#include<iostream>
#include<algorithm>
#include<string>
#include<math.h>
#include<stdlib.h>
#include <iostream>
#include <vector>
#include <queue>
using namespace std ;

int main() {	
	string s;
	cin>>s;
	int max=0;
	for(int i=0;i<s.size();i++){
		for(int j=i+1;j<s.size();j++){
			int count=0;
			for(int k=0;k<(s.size()-j);k++){
				if(s[i+k]==s[j+k]) count++;
				else break;
			}
			if(count>max) max=count;
		}
	}
	cout<<max;
}
/*


ababcdabcefsgg

*/

 

第四题:https://www.nowcoder.com/practice/2d47abf176f7486db0d707088404db8a?tpId=90&tqId=30883&rp=6&ru=/ta/2018test&qru=/ta/2018test/question-ranking

题目描述

回形数是一个矩阵输出,从矩阵的左上角往右开始打印数字0,遇到矩阵边界时,顺时针90方向继续打印,并数字增长1,如此类推直到把矩阵填满,输入一个整形宽和高单位,每输出一个数字,占用1单位宽高空间,根据入参打印出对应的回形数

输入描述:

矩阵的宽高

输出描述:

回字形的矩阵

按他的说法遍历数组一遍并且赋值,比较麻烦这题,但不难。

#include<iostream>
#include<algorithm>
#include<string>
#include<math.h>
#include<stdlib.h>
#include <iostream>
#include <vector>
#include <queue>
using namespace std ;

int main() {	
	int right,bottom;
	cin>>right>>bottom;
	int n=right,m=bottom;
	int top=0,left=0;
	int a[100][100];
	int flag=0;
	int x=0,y=0;
	int count=0;
	while(1){
//		cout<<x<<' '<<y<<' '<<flag<<endl;
		if(flag==0) {
			a[x][y]=count;
			if(y+1<right) y=y+1;
			else{
				count++;
				flag=1;
				x=x+1;
				top++;
				if(x>=bottom) break;
			}
		}
		else if(flag==1) {
			a[x][y]=count;
			if(x+1<bottom) x=x+1;
			else{
				flag=2;
				count++;
				right--;
				if(y-1<left) break;
				else y=y-1;
			}
		}
		else if(flag==2) {
			a[x][y]=count;
			if(y-1>=left) y=y-1;
			else{
				count++;
				flag=3;
				bottom--;
				if(x-1<top) break;
				else x=x-1;
			}
		}
		else if(flag==3) {
			a[x][y]=count;
			if(x-1>=top) x=x-1;
			else{
				count++;
				flag=0;
				left++;
				if(y+1>right) break;
				else y=y+1;
			}
		}
	}
	for(int i=0;i<m;i++){
		for(int j=0;j<n;j++){
			cout<<a[i][j];
		}
		cout<<endl;
	}
}
/*


8 3

*/

第五题:https://www.nowcoder.com/practice/ce968b4765d94c45af3f639c133da040?tpId=90&tqId=30891&rp=6&ru=/ta/2018test&qru=/ta/2018test/question-ranking

题目描述

小摩手里有一个字符串A,小拜的手里有一个字符串B,B的长度大于等于A,所以小摩想把A串变得和B串一样长,这样小拜就愿意和小摩一起玩了。

而且A的长度增加到和B串一样长的时候,对应的每一位相等的越多,小拜就越喜欢。比如"abc"和"abd"对应相等的位数为2,为前两位。

小摩可以在A的开头或者结尾添加任意字符,使得长度和B一样。现在问小摩对A串添加完字符之后,不相等的位数最少有多少位?

输入描述:

第一行 为字符串A,第二行 为字符串B,
A的长度小于等于B的长度,B的长度小于等于100。
字符均为小写字母。

输出描述:

输出一行整数表示A串添加完字符之后,A B 不相等的位数最少有多少位?

比较两个字符串最大重叠数目;就是字符串A与字符串B从第一位开始遍历比较,由于有限制,所以要控制边界。

#include<iostream>
#include<algorithm>
#include<string>
#include<math.h>
#include<stdlib.h>
#include <iostream>
#include <vector>
#include <queue>
using namespace std ;

int main() {	
	string sa,sb;
	cin>>sa>>sb;
	int max=0;
	for(int i=0;i<sb.size()-sa.size()+1;i++){
		int count=0;
		for(int j=0;j<sa.size();j++){
			if(sa[j]==sb[i+j]){
				count++;
			}
		}
		if(count>max) max=count;
	}
	cout<<sa.size()-max;
}
/*


1 -1 2 -2 3 -3 4

*/

第六题:https://www.nowcoder.com/practice/1712e1cb393b499ba52036b702990839?tpId=90&tqId=30893&rp=6&ru=/ta/2018test&qru=/ta/2018test/question-ranking

题目描述

小摩有一个N个数的数组,他想将数组从小到大 排好序,但是萌萌的小摩只会下面这个操作:

任取数组中的一个数然后将它放置在数组的最后一个位置。

问最少操作多少次可以使得数组从小到大有序?

输入描述:

首先输入一个正整数N,接下来的一行输入N个整数。(N <= 50, 每个数的绝对值小于等于1000)

输出描述:

输出一行操作数

只要看输入数组按排序对了几个,剩下几个就是需要操作的次数。

 

#include<iostream>
#include<algorithm>
#include<string>
#include<math.h>
#include<stdlib.h>
#include <iostream>
#include <vector>
#include <queue>
using namespace std ;

int main() {	
	int n;
	cin>>n;
	int a[10000],b[10000];
	for(int i=0;i<n;i++){
		cin>>a[i];
		b[i]=a[i];
	} 
	sort(b,b+n);

	int index=0;
	for(int i=0;i<n;i++){
		if(b[index]==a[i]){
			index++;	
		}
	}
	cout<<n-index;
	
}
/*


1 -1 2 -2 3 -3 4

*/

第七题:https://www.nowcoder.com/practice/6e6ad6338289498da79b7afb60e823b3?tpId=90&tqId=30894&rp=6&ru=/ta/2018test&qru=/ta/2018test/question-ranking

题目描述

牛牛有两个字符串A和B,其中A串是一个01串,B串中除了可能有0和1,还可能有'?',B中的'?'可以确定为0或者1。 寻找一个字符串T是否在字符串S中出现的过程,称为字符串匹配。牛牛现在考虑所有可能的字符串B,有多少种可以在字符串A中完成匹配。

例如:A = "00010001", B = "??"
字符串B可能的字符串是"00","01","10","11",只有"11"没有出现在字符串A中,所以输出3

输入描述:

输入包括两行,第一行一个字符串A,字符串A长度length(1 ≤ length ≤ 50),A中每个字符都是'0'或者'1'。
第二行一个字符串B,字符串B长度length(1 ≤ length ≤ 50),B中的字符包括'0','1'和'?'。

输出描述:

输出一个整数,表示能完成匹配的字符串种数。

查看是否匹配,再用一个容器存匹配字符串,如果容器里有这个字符串,则不加入,否则加入容器。


#include<iostream>
#include<algorithm>
#include<string>
#include<math.h>
#include<stdlib.h>
#include <iostream>
#include <vector>
#include <queue>
#include <set>

using namespace std ;
 
int main() {	
	string sa,sb;
	cin>>sa>>sb;
	set<string> str;
	int max=0;
	for(int i=0;i<sa.size()-sb.size()+1;i++){
		int flag=0;
		string ss;
		for(int j=0;j<sb.size();j++){
			if(sb[j]!=sa[i+j]&&sb[j]!='?'){
				flag=1;
				break;
			}
			ss+=sa[i+j];
		}
		if(flag==0){
//			cout<<ss<<endl;
			if (str.count(ss)) continue;
			else{
				max++;
				str.insert(ss);
			}
			
		}
	}
	cout<<max;
}

/*

00010001
??


*/

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值