阿里+贝壳+荣耀笔试复盘

阿里第一题:
输入一个编号 n代表数中中元素个数,第二行输入若干个整数,代表数组中的元素
在一行中输出一个编号,代表在这个元素后分割可以使得两个数组的权重的乘积最大。
如果有多个最佳答案,任意输出一个即可。
输入

3
1 2 3

输出

2

思路:
两个数加起来固定,在变化过程中求乘积最大,则x+y=m,我们求 2xy=m2-x2-y2,求xy的最大值就是求x2+y2的最小值。
x2+y2=2x2-2mx+m2 ,当且仅当x=m/2的时候,x2+y2最小。
这给我们启示,我们划分数组的时候两侧元素之和越接近越相等,乘积之和就越大,这意味着sum-temp越接近temp,即sum-2*temp越接近0!

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
int n,a[N],sum,tmp,res,gap=1e18;
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i],sum+=a[i];
	for(int i=1;i<n;i++){
		tmp+=a[i];
		if(abs(sum-2*tmp)<gap) gap=abs(sum-2*tmp),res=i;
	}
	cout<<res<<endl;
	return 0;
}

荣耀笔试第一题
在这里插入图片描述

// 6 3 1 14
#include<bits/stdc++.h>
using namespace std;

const int inf=99999;
int main()
{
    int n,x,y;
    scanf("%d,%d,%d",&n,&x,&y);
    int pos=0;
	int cnt=0;	
    int dis=x-y;
    for(int i=1;i<inf;i++)
    {
        if(pos+x<n){
			pos+=dis;
       		cnt++;
		}
        else
            break;
    }
    int rest=n-pos;
    double min1=x/5.0; //路程除以时间等于速度
    int sum=5*cnt+ceil((rest/min1));  //时间向上取整 
   	cout<<sum<<endl;
   	return 0;
}
// 6 3 1 14
// 10 4 1
#include<bits/stdc++.h>
using namespace std;


int main()
{
    int n,x,y;
  	scanf("%d,%d,%d",&n,&x,&y);
    int dis=x-y;
	int count=n/dis;
	if(dis*(count-1)+x>n)
		count--;
	int rest=n-count*dis;
	double min1=x/5.0;
	 
    int sum=5*count+ceil((rest/min1));  //时间向上取整 
   	cout<<sum;
   	return 0;
}

荣耀笔试第三题
输入一个数字M,存在两个质数相加等于M,求所有符合这样条件的质数组,同时输出质数组中差距最小的一组输出,且输出时候两个质数中较小的一个放在前面。
思路:
两个数加起来等于M,这两个数的最大值必然不可能超过M,同时,我只需要要搜索M的一半区间即可,因为不需要重复解,且能保证找到的第一个数是小的。
one two 加起来等于M 我再代入质数判断函数中判断即可。这里质数判断函数是通过遍历输入的数字,看他是否能被其他因子整除。注意到要增加对1的判断。
事实上,判断质数,我们可以i<=num/2 就行了,因为注意到,i大于num/2之后为了乘积等于num,这个因子就小于2,没有意义了。

#include<bits/stdc++.h>
using namespace std;
bool isNum(int num){
    for(int i=2;i<num;i++){
        if(num%i==0){
            return false;
            break;  
        }
    }
    if(num==1) return false; 
    return true;
}

int main(){
    int M; cin>>M;
    vector<vector<int>>res;
    for(int i=2;i<=M/2;i++){
        int one=i;
        int two= M-i;
        if(isNum(one) && isNum(two)){
            vector<int>temp; 
            temp.push_back(one);
            temp.push_back(two);
            res.push_back(temp);
        }        
    }
    int MinValue=9999999;     int out1=0,out2=0;    int t;
    for(int i=0;i<res.size();i++){
        t=res[i][1]-res[i][0];
        if(t<MinValue){
            out1=res[i][0];   out2=res[i][1];      MinValue=t;
        }
    }
    if(res.size()==0)
        cout<<0<<endl;
    else{
        cout<<out1<<' '<<out2<<endl;
    }     
    return 0;
}

荣耀笔试第二题:
URL1:/ab/
URL2:/vjk/
类似这样的URL,我们需要合并URL1和URL2,如果URL1的尾巴和URL2的前面都有/,要去重,如果都没有,要增加,如果都是空的,返回/,反正题目会因为一些原因考虑不全面,需要把所有情况列出来,包括A空A不空等。
思路:
   代码没有保存,懒得写了,核心思路就是分析,当A等于空的时候和A不空的时候来分析。当A为空的时候,判断B是不是空,是返回/ 不是返回B
   当A不为空的时候,B若不空,判断A的尾巴和B的开头是不是都是/,是的话从B的1位开始走起来,当B是空,返回A。

#include<bits/stdc++.h>
using namespace std;
int main(){
	vector<string>res(2);
	string s;
	getline(cin,s);
	stringstream ss(s);
	string temp;
	int index=0;
	while(getline(ss,temp,',')){
		res[index]=temp; index++;
	}
	//完成输入
	string one=res[0];
	string two=res[1];

	// 1为空的情况 
	if(one.size()==0){
		if(two.size()==0)
			cout<<'/';
		if(two.size()!=0){
			if(two[0]=='/')
				cout<<two;
			else{
				string temp;  
				temp="/";   //试试看把这行去掉 会不会提高通过率 
				two=temp+two;
				cout<<two;
			}			
		}		
	} 
//	
	///1不为空的情况
	int size1=one.size();
	if(one.size()!=0){
		if(two.size()==0){
			if(one[0]=='/')
				cout<<one;
			else
				cout<<"/"+one; 
		} 
		
		/
		if(two.size()!=0){
			if(one[size1-1]=='/' && two[0]=='/'){
				string temp2;
				temp2=one+two.substr(1);
				cout<<temp2;
			}
			
			else if(one[size1-1]!='/'&& two[0]!='/'){
					string temp3;
					temp3=one+'/'+two;
					cout<<temp3;
				}
			else if(one[size1-1]=='/'|| two[0]=='/')
				cout<<one+two;
							
	}				
}
}

贝壳笔试第一题:
  贝壳A的第二第三题代码怎么没保存上,算了,那就看下第一题把。
  第一题看起来挺简单的,输入N,M代表有N行农田,M千克肥料,拖拉机从上往下对农行施肥,每行施肥1kg,施肥到N行,掉头继续施肥,如此反复直到拖拉机把M千克的肥料用完。
  要求输出一个数组,返回每一行施肥的重量!
思路:
一开始打算直接M%N取余,但是注意到第二次返回施肥的时候,最后一行是没有给他施肥的。所以并不是简单的施肥计算。思路如下
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
/*int main(){
    int n; cin>>n;
    vector<string>s;
    for(int i=0;i<=n;i++){
        string temp;
        getline(cin,temp);
        s.push_back(temp);
    }
          
}
*/
int main(){
      int n,m;
	  cin>>n>>m;
	  int count=m/(n-1);
	  vector<int>res(n);
	  for(int i=1;i<n-1;i++)
	  	res[i]=count;
	  res[n-1]=count/2;
	  res[0]=(count>>1)+(count&1);	
	  int curr=0,step=1;
	  if(count&1){
	  	curr=n-1;
		  step=-1;		
	  }
	  int left=m%(n-1);
	  while(left-->0){
	  	res[curr]++;
	  	curr+=step;
	  }
	  for(int i=0;i<res.size();i++)
	  	cout<<res[i]<<" ";
}

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值