腾讯2017暑期实习生编程题

三个题

难度 第三题>第一题>第二题 

 

第一题

构造回文

链接:https://www.nowcoder.com/questionTerminal/28c1dc06bc9b4afd957b01acdf046e69
来源:牛客网

给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?
输出需要删除的字符个数。
 

输入描述:

输入数据有多组,每组包含一个字符串s,且保证:1<=s.length<=1000.

输出描述:

对于每组数据,输出一个整数,代表最少需要删除的字符个数。

示例1

输入

abcda
google

输出

2
2
///第一题
#include<bits/stdc++.h>
typedef long long ll;
const int maxn =100010;
using namespace std;
int a[maxn];
int dp[1010][1010];
int n;
int ans=0;

string s1,s2;

int fun(string s1,string s2){   ///求两个串的最大公共子串(子串可以不连续)
    memset(dp,0,sizeof(dp));    //数组清空为 0
    n=s1.length();      //求长度

    //简单动态规划     dp[i+1][j+1] 表示 s1的前i个字符组成的字符串  和  s2的前j个字符组成的字符串 的最大公共子串
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(s1[i]==s2[j])dp[i+1][j+1]=dp[i][j]+1;
            else dp[i+1][j+1]=max(dp[i+1][j],max(dp[i][j+1],dp[i][j]));
        }
    }
    ans=n-dp[n][n];
    return ans;
}
int main(){
    while(cin>>s1){
        s2=s1;
        reverse(s2.begin(),s2.end());   //翻转字符串
        fun(s1,s2);
        cout<<ans<<endl;
    }
}

第二题

算法基础-字符移位

链接:https://www.nowcoder.com/questionTerminal/7e8aa3f9873046d08899e0b44dac5e43
来源:牛客网

小Q最近遇到了一个难题:把一个字符串的大写字母放到字符串的后面,各个字符的相对位置不变,且不能申请额外的空间。
你能帮帮小Q吗?

 

 

输入描述:

 

输入数据有多组,每组包含一个字符串s,且保证:1<=s.length<=1000.


 

输出描述:

 

对于每组数据,输出移位后的字符串。

示例1

输入

AkleBiCeilD

输出

kleieilABCD
///第二题
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;

string s;
int len;
int main(){
    while(cin>>s){
        len=s.length();
        for(int i=0;i<len;i++) if(s[i]>='a'&&s[i]<='z')cout<<s[i];

        for(int i=0;i<len;i++)if(s[i]>='A'&&s[i]<='Z')cout<<s[i];
        cout<<endl;
    }

    return 0;
}

 

第三题

有趣的数字

链接:https://www.nowcoder.com/questionTerminal/af709ab9ca57430886632022e543d4c6
来源:牛客网

小Q今天在上厕所时想到了这个问题:有n个数,两两组成二元组,相差最小的有多少对呢?相差最大呢?

 

 

输入描述:

 

输入包含多组测试数据。
对于每组测试数据:
N - 本组测试数据有n个数
a1,a2...an - 需要计算的数据
保证:
1<=N<=100000,0<=ai<=INT_MAX.


 

输出描述:

 

对于每组数据,输出两个数,第一个数表示差最小的对数,第二个数表示差最大的对数。

示例1

输入

6
45 12 45 32 5 6

输出

1 2

#include<bits/stdc++.h>
typedef long long ll;
const int maxn =100010;
const int inf=0x7fffff; ///自己定义一个比较大的数
using namespace std;

int n;
int a[maxn];
set<int>q1;     //集合(不可重复)
multiset<int>q2;    //集合(可以重复)
int ans1,ans2,t1,t2,flag;

int main(){
    while(scanf("%d",&n)!=EOF){
        ///初始化
        flag=ans1=ans2=0;
        q1.clear();q2.clear();
        flag=inf;

        ///输入
        for(int i=0;i<n;i++){scanf("%d",&a[i]);q2.insert(a[i]);q1.insert(a[i]);}

        sort(a,a+n);    ///排序

        t1=q2.count(a[0]);
        t2=q2.count(a[n-1]);
        ans2=t1*t2;     ///求第二个数表示差最大的对数   第二个数   肯定是最大值-最小值。 那么个数肯定是最大数的个数*最小数的个数

        for(int i=0;i<n-1;i++){
            flag=min(flag,a[i+1]-a[i]);
        }


            ///求第一个数  分两种考虑,    相差为 0,   相差大于0 (肯定不会有小于0)
        if(flag==0){    //如果相差最小为 0  那就找数组中相同数的个数
            set<int>::iterator it=q1.begin();
            for(;it!=q1.end();it++){
                t1=*it;
                t2=q2.count(t1);
                if(t2>1)ans1+=(t2*(t2-1)/2);
            }
        }   //如果最小相差大于0   那就表示数组中所有的数都不相同,   所有就看看有几个这样的差值就ok
        else{
            for(int i=1;i<n;i++)if(a[i]-a[i-1]==flag)ans1++;
        }
        cout<<ans1<<' '<<ans2<<endl;
    }
    return 0;
}

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值