给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?
你能帮帮小Q吗?
小Q今天在上厕所时想到了这个问题:有n个数,两两组成二元组,差最小的有多少对呢?差最大呢?
输出需要删除的字符个数。
解题思路:求一个字符串自身与他的逆序列的最长公共子序列。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N =1005;
int dp[N][N];
int main()
{
char s1[N],s2[N];
while(cin>>s1)
{
memset(s2,0,sizeof(s2));
memset(dp,0,sizeof(dp));
int len=strlen(s1);
for(int i=len-1;i>=0;i--)
s2[len-i-1]=s1[i];
//cout<<s1<<" "<<s2<<endl;
for(int i=1;i<=len;i++)
{
for(int j=1;j<=len;j++)
{
if(s1[i-1]==s2[j-1])
dp[i][j]=dp[i-1][j-1]+1;
else
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
cout<<len-dp[len][len]<<endl;
}
return 0;
}
小Q最近遇到了一个难题:把一个字符串的大写字母放到字符串的后面,各个字符的相对位置不变,且不能申请额外的空间。
你能帮帮小Q吗?
水题
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cctype>
using namespace std;
const int N = 1005;
int main()
{
char s1[N],s2[N];
while(~scanf("%s",s1))
{
int len=strlen(s1);
memset(s2,0,sizeof(s2));
int j=0;
for(int i=0;i<len;i++)
{
if(isupper(s1[i]))
s2[j++]=s1[i];
else
printf("%c",s1[i]);
}
printf("%s\n",s2);
}
return 0;
}
小Q今天在上厕所时想到了这个问题:有n个数,两两组成二元组,差最小的有多少对呢?差最大呢?
解题思路:
先排序,差值最大的肯定是最大数减去最小数,我们只要求出最大数,最小数的个数,然后相乘就可以了。
差值最小的肯定相邻元素之前的差值,我们需要判断最小值是否为0。为0时,求出相等元素的个数。不为0,求出相邻元素差值等于最小值的个数
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <climits>
using namespace std;
const int N=100005;
int a[N];
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=0; i<n; i++)
scanf("%d",&a[i]);
sort(a,a+n);
int min_s=INT_MAX;
for(int i=1; i<n; i++)
{
min_s=min(a[i]-a[i-1],min_s);
}
int min_cnt=0,max_cnt=0;
int x=0,y=0;
for(int i=0; i<n; i++)//求最小数的个数和最大数的个数
{
if(a[i]==a[0])
x++;
if(a[i]==a[n-1])
y++;
}
max_cnt=x*y;//个数相乘
if(min_s==0)//最小差值为0
{
for (int i=1; i<n; i++)//求相等元素的个数
{
int j=i-1;
while (a[j]==a[i] && j>=0)
{
min_cnt++;
j--;
}
}
}
else
{
for(int i=1; i<n; i++)//求相邻元素的差值为最小值的个数
{
if(a[i]-a[i-1]==min_s)
min_cnt++;
}
}
//printf("%d %d\n",min_s,max_s);
printf("%d %d\n",min_cnt,max_cnt);
}
return 0;
}