【牛客网】网易2017秋招编程题集合

1[编程题]回文序列

如果一个数字序列逆置之后跟原序列是一样的就称这样的数字序列为回文序列。例如:
{1, 2, 1}, {15, 78, 78, 15} , {112}
是回文序列
{1, 2, 2}, {15, 78, 87, 51} ,{112, 2, 11}
不是回文序列。
现在给出一个数字序列,允许使用一种转换操作:
选择任意两个相邻的数,然后从序列移除这两个数,并用这两个数字的和插入到这两个数之前的位置(只插入一个和)
现在对于所给序列要求出最少需要多少次操作可以将其变成回文序列。

输入描述:

输入为两行,第一行为序列长度n ( 1 ≤ n ≤ 50)

第二行为序列中的n个整数item[i]  (1 ≤iteam[i] ≤ 1000),以空格分隔。

 

输出描述:

输出一个数,表示最少需要的转换次数

 

输入例子:

4

1 1 1 3

 

输出例子:

2

 

 

一、使用递归,仅能通过60%的测试用例

/*
您的代码已保存
运行超时:您的程序未能在规定时间内运行结束,请检查是否循环有错或算法复杂度过大。
case通过率为60.00%
*/
 
#include<iostream>
#include<vector>
#include<limits.h>
using namespace std;
 
bool judge(vector<int> num){
       //判断num是否是个回文序列
       int len=num.size();
       int left=0;
       int right=len-1;
       while(left<right){
              if(num[left] != num[right]){
                     return false;
              }else{
                     left++;
                     right--;
              }
       }
       return true;
        
}
 
 
int shift(vector<int> item, int n){
       //返回需要转换的次数
       if(n==0 || n==1){
              return 0;
       }else if(n==2){
              if(item[0] ==item[1]){
                     return 0;
              }else{
                     return 1;
              }
       }else if(n==3){
              if(item[0] == item[2]){
                     return 0;;
              }else{
                     int min_count=INT_MAX;
                     for(int i=0;i<n-1;i++){
                            vector<int>item1=item;
                            int tmp;
                            tmp = item1[i] +item1[i+1];
                            vector<int>::iteratorit=item1.begin()+i;
                            item1.erase(it);
                            it=item1.begin()+i;
                            item1.erase(it);
                            it=item1.begin()+i;
                            item1.insert(it,tmp);
                            tmp = shift(item1,item1.size())+1;
                            if(tmp<min_count){
                                   min_count =tmp;
                            }
                     }
                     return min_count;
              }
       }else{
              if(judge(item)){
                     return 0;
              }else{
                     int min_count=INT_MAX;
                     for(int i=0;i<n-1;i++){
                            vector<int>item1=item;
                            int tmp;
                            tmp = item1[i] +item1[i+1];
                            vector<int>::iteratorit=item1.begin()+i;
                            item1.erase(it);
                            it=item1.begin()+i;
                            item1.erase(it);
                            it=item1.begin()+i;
                            item1.insert(it,tmp);
                            tmp = shift(item1,item1.size())+1;
                            if(tmp<min_count){
                                   min_count =tmp;
                            }
                     }
                     return min_count;
              }
       }
        
}
 
 
int main(){
       int n; //序列长度n
       while(cin>>n){
              vector<int> item;
              int tmp,i,j;
              for(i=0;i<n;i++){
                     cin>>tmp;
                     item.push_back(tmp);
              }//输入
             
              cout<<shift(item,item.size())<<endl;
               
               
       } //while
       return 0;
      
}


二、AC代码

思路:left = 0, right = n-1

(1)比较左边第一个元素和右边第一个元素,如果两个数相等,则把他们从数组中移除(这里并不是真的移除,而是left++,right--),否则执行(2)或者(3)。如果还有剩余的元素,继续(1)

(2)如果左边的元素小于右边的元素(item[left] < item[right]),则把左边的第一个元素加第二个元素的结果成为第二个元素,left++,记一次加法,继续(1)

(3)如果右边的元素小于左边的元素(item[left] > item[right]),则把右边的第一个元素加第二个元素的结果成为第二个元素,right--,记一次加法,继续(1)。

循环执行条件为left<right。最后输出计数count即可。

 

c++代码:

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

int cal(vector<int> a, int start, int end){
    int cnt=0;
    if(start >= end){
        return cnt;
    }
    while(start<end){
        if(a[start] == a[end]){
            start++;
            end--;
        }else if(a[start] < a[end]){
            a[start+1] = a[start] + a[start+1];
            start++;
            cnt++;
        }else{
            a[end-1] = a[end-1]+a[end];
            end--;
            cnt++;
        }


    }//while
    return cnt;

}


int main(){
    int n;  //表示序列长度n
    while(cin>>n){
        vector<int> item;
        for(int i=0;i<n;i++){
            int tmp;
            cin>>tmp;
            item.push_back(tmp);
        }//for
        cout<<cal(item, 0, item.size()-1)<<endl;

    }//while
    return 0;
}



2、[编程题]优雅的点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值