给定一个字符串,你可以删除多个(可以是 0) 相同 的字符,这样操作之后,你能否得到一个回文串?如果能,求最小化删除的个数。
输入格式
多组数据。
每一组数据包含两行,分别为字符串的长度 N,以及一个仅由小写字母组成的字符串 S。
输出格式
对于每一组数据,输出一行。
如果不可能得到一个回文串,输出 −1。反之则输出最小操作次数
#include<bits/stdc++.h>
using namespace std;
char str[100005];
int len;
int judge(char a,int l,int r){
int num=0,flag=0;
while(l<r){
if(str[l]!=str[r]){
if(str[l]==a){
num++,l++,flag=1;
}
else if(str[r]==a){
num++,r--,flag=1;
}
}
if(str[l]==str[r]){
l++,r--,flag=1;
}
if(!flag){
return -1;
}
flag=0;
}
return num;
}
void findans(){
int l=1,r=len,ans_l,ans_r,flag2=0;
char flag='0';
while(l<r){
if(str[l]!=str[r]){
flag2=1;
ans_l=judge(str[l],l,r);
ans_r=judge(str[r],l,r);
if(ans_l==ans_r==-1){
cout<<"-1"<<endl;
}
else if(ans_l!=-1&&ans_r==-1){
cout<<ans_l<<endl;
}
else if(ans_l==-1&&ans_r!=-1){
cout<<ans_r<<endl;
}
else if(ans_l<ans_r){
cout<<ans_l<<endl;
}
else{
cout<<ans_r<<endl;
}
break;
}
l++,r--;
}
if(!flag2){
cout<<"0"<<endl;
}
}
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>len;
for(int i=1;i<=len;i++){
cin>>str[i];
}
findans();
}
return 0;
}
给定一个长度为 n 的数组 a_1,a_2,…,a_n,接下来进行 n−1次操作。每次选择一个下标 x ,将 a_x 和 a_x+1合并成 a_x * a_(x+1) mod1000003,并且你会获得 (a_x−a__(x+1))^2 的分数。
所以每次操作后,数组的长度将会减 1,当最后只剩下一个元素时停止操作。输出最终能获得的最大分数。
输入格式
第一行一个数字 n。
接下来一行 n 个整数 a_1,a_2,…,a_n
输出格式
一个数,表示答案。
#include<bits/stdc++.h>
using namespace std;
#define mod 1000003
unsigned long long dp[305][305],num[305],x[305][305],book[305][305];
int n;
inline unsigned long long finddp(int l,int r){ //dp过程
if(book[l][r]){
return book[l][r]; //记忆化
}
if(l==r){
return 0;
}
else{
for(int k=l;k<=r-1;k++){
dp[l][r]=max(dp[l][r],finddp(l,k)+finddp(k+1,r)+(x[l][k]-x[k+1][r])*(x[l][k]-x[k+1][r]));
}
}
book[l][r]=dp[l][r];
return dp[l][r];
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
x[i][j]=1;
}
}
for(int i=1;i<=n;i++){
cin>>num[i];
}
for(int i=1;i<=n;i++){
for(int k=i;k<=n;k++){
for(int j=i;j<=k;j++){
x[i][k]=(x[i][k]*num[j])%mod;
}
}
}
cout<<finddp(1,n)<<endl;
return 0;
}
接着《饿饿 饭饭》 的故事,在两天后,食堂的工作人员回来了,整个食堂又回到了原来井井有条的状态。
两个月后,由于天气越来越热,大家的胃口越来越小了,作为食堂管理员的CC非常担心孩子们的身体健康,所以他决定开展一个活动来调动孩子们吃饭的积极性,顺便考验一下孩子们的数学水平。活动内容如下:
先让每一个孩子都抽一个球,每一个球上有一个数字, 然后给这个孩子n个数字,每一个孩子都有无数次操作机会,每一次都会选中一个数将它乘上2,或者乘上3,请问这个孩子可以通过上面的操作将这n个数都变成相同的吗?
如果回答正确,这个回答正确的孩子就可以得到一份免费的午餐,但是这对于孩子们来说是在是太困难了,但是他们都想吃到免费的午餐,所以他们都想请你告诉他们正确的答案,让他们都迟到免费的午餐。
输入格式
第1行给定一个数T,表示有T个小孩子请你告诉他正确的答案。
第2到T+1行,第1个数是每个孩子抽到的数字n,第2到n+1个数是对应的n个数字。
输出格式
如果可以变成相同的,输出YES。如果不能变成相同的,输出NO。
数据规模
1≤T≤100,1≤n≤2×105,1≤a_i≤109
数据保证∑T_i=1n≤2×105
#include<bits/stdc++.h>
using namespace std;
inline long long search(long long x,long long a){ //二分搜索
int l=0,r=50;
while(l!=r-1){
int mid=(l+r)/2;
if(x%(int)pow(a,mid)){
r=mid;
}
else{
l=mid;
}
}
return (long long)pow(a,l);
}
inline long long findlea(long long num){
while(1){
if(!(num%2)){
num/=search(num,2); //除以2
continue;
}
else if(!(num%3)){
num/=search(num,3); //除以3
continue;
}
break;
}
return num;
}
int main(){
long long t,n,num,flag,flag0=0;
scanf("%lld",&t);
for(int i=1;i<=t;i++){
scanf("%lld",&n);
scanf("%lld",&num);
flag=findlea(num);
for(int a=2;a<=n;a++){
scanf("%lld",&num);
if(findlea(num)!=flag){ //如果x不同就代表不行
flag0=1;
}
}
if(!flag0){
printf("YES\n");
}
else{
printf("NO\n");
}
flag0=0;
}
return 0;
}