腾讯2017暑期实习生编程题

题目链接

题目都比较简单,太久没做题了有点生疏反应有点慢,做题时间有点长。

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

题解:设字符串长度为n,构造另一个串为原串的回文串,求两个串的最长公共子序列的长度len即可,n-len即为答案。

 

#include <bits/stdc++.h>
using namespace std;
int dp[1005][1005];
int main()
{
    char c1[1005],c2[1005];
    while(scanf("%s",c1)!=EOF){
        int len=strlen(c1);//printf("%d\n",len);
        for(int i=len;i>=1;i--) c1[i]=c1[i-1];
        for(int i=1;i<=len;i++) c2[i]=c1[len+1-i];
        //puts(c1+1);puts(c2+1);
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=len;i++)
        for(int j=1;j<=len;j++)
        {
            if(c1[i]==c2[j]) dp[i][j]=dp[i-1][j-1]+1;
            else dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
        }
        printf("%d\n",len-dp[len][len]);
    }
    return 0;
}

 

 

 

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

题解:先输出小写再输出大写就行了。

 

#include <bits/stdc++.h>
using namespace std;
int main()
{
    string c;
    while(cin>>c){
        for(int i=0;i<c.length();i++){
            if(islower(c[i])) printf("%c",c[i]);
        }
        for(int i=0;i<c.length();i++){
            if(isupper(c[i])) printf("%c",c[i]);
        }
        printf("\n");
    }
    return 0;
}

 

 

 

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

题解:首先肯定是排序,然后处理一下,开两个数组一个存数的大小,一个存数的数目。

  最小值有重复数就是0,没重复就是相邻最小值,分别算一下即可。 
  最大值如果只有一种数那么就有C(N,2)对,否则就是第一种和最后一种数目的乘积。
  也就是说要注意考虑两种特殊情况,
  第一种是只有一种数的情况,单独拿出来算就行了,
  第二种是有多种数但是也有重复的也就是最小值也为0。 
  还要注意sum数组每个都要+1,首位不要加两次。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int n,cnt;
ll data[N];
ll sum[N],type[N];
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        memset(data,0,sizeof(data));
        memset(sum,0,sizeof(sum));
        memset(type,0,sizeof(type));
        cnt=0;
        for(int i=0; i<n; i++)
            scanf("%lld",&data[i]);
        sort(data,data+n);
        type[cnt]=data[0];
        ll mn=1000000000,mx=-1,ansmn=0,ansmx=0;
        for(int i=1; i<n; i++)
            if(data[i]==data[i-1])
            {
                sum[cnt]++;
                if(sum[cnt]>=1) mn=0;
            }
            else
                type[++cnt]=data[i];
        for(int i=0;i<=cnt;i++)
        sum[i]++;
        //for(int i=0;i<=cnt;i++)
        //printf("%lld %lld\n",type[i],sum[i]);
        //printf("%lld\n",mn);
        if(cnt==0)
        {
            ansmn=n*(n-1)/2;
            ansmx=ansmn;
        }
        else
        {
            if(mn==1000000000)
            {
                for(int i=1; i<=cnt; i++)
                mn=min(type[i]-type[i-1],mn);
                for(int i=1; i<=cnt; i++)
                if(type[i]-type[i-1]==mn) ansmn+=sum[i]*sum[i-1];
            }
            else if(mn==0)
            {
                for(int i=0; i<=cnt; i++)
                ansmn+=sum[i]*(sum[i]-1)/2;
            }
            ansmx=sum[cnt]*sum[0];
        }
        printf("%lld %lld\n",ansmn,ansmx);
    }
    return 0;
}
/*
6
45 12 45 32 5 6
*/

// 1 2

 

 第三题的另一种解法:

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
const int inf=0x3f3f3f3f;
typedef long long ll;
ll data[N],n,x;
int main()
{
    while(cin>>n)
    {
        memset(data,0,sizeof(data));
        for(int i=0; i<n; i++) cin>>data[i];
        sort(data,data+n);
        if(n==1) printf("0 0\n");
        else
        {
            ll mn=data[0],mx=data[n-1];//数组最小值和最大值
            if(mn==mx)
            {
                printf("%lld %lld\n",n*(n-1)/2,n*(n-1)/2);
            }
            else
            {
                ll num_mn=1,num_mx=1;//数组最小值和最大值各有多少个
                for(int i=1; i<n; i++)
                    if(data[i]==data[i-1]) num_mn++;
                    else break;
                for(int i=n-2; i>=0; i--)
                    if(data[i]==data[i+1]) num_mx++;
                    else break;
                int f=0;
                for(int i=1; i<n; i++)
                {
                    if(data[i]==data[i-1])
                    {
                        f=1;
                        break;
                    }
                }
                //注意这里要判断最小值是不是0 如果是0就要算c(n,2)的个数
                if(f)
                {
                    ll ans=0,sum=1;
                    for(int i=1; i<n; i++)
                    {
                        if(data[i]==data[i-1])
                        {
                            sum++;
                        }
                        else
                        {
                            ans+=sum*(sum-1)/2;
                            sum=1;
                        }
                        if(i==n-1) ans+=sum*(sum-1)/2;
                    }
                    printf("%lld %lld\n",ans,num_mn*num_mx);
                }
                else
                {
                    //数组差的最小值 数组差的最小值的个数
                    ll ans_del_mn=inf,num_del_mn=0;
                    for(int i=1; i<n; i++)
                    {
                        if(data[i]-data[i-1]<ans_del_mn)
                        {
                            ans_del_mn=data[i]-data[i-1];
                            num_del_mn=0;
                        }
                        if(data[i]-data[i-1]==ans_del_mn) num_del_mn++;
                    }
                    printf("%lld %lld\n",num_del_mn,num_mn*num_mx);
                }
            }
        }
    }
    return 0;
}

 

posted @ 2017-02-19 19:50  Ritchie丶  阅读(1348)  评论(0编辑  收藏  举报