三个题
难度 第三题>第一题>第二题
第一题
构造回文
链接: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;
}