hnucm-oj1176 - 2021年春季学期《算法分析与设计》练习8

hnucm-oj1176 - 2021年春季学期《算法分析与设计》练习8

A 解密

题目描述
湖南中医药大学有含浦、东塘 2 个校区,学校办学历史悠久,前身为 1934 年的湖南国医专科学校,1953
年创办湖南中医进修学校,1960 年创建普通高等本科院校——湖南中医学院,1979 年成为全国首批取得
中医类研究生学历教育资格的院校,1990 年原湖南科技大学成建制并入湖南中医学院,2002 年与湖南省
中医药研究院合并,2006 年经教育部批准更名为湖南中医药大学,2012 年进入湖南省一本招生序列。
目前,学校与湖南省中医药研究院实行校院合一的管理体制。学校学科门类齐全、中医药特色鲜明。学校
设有 18 个学院、24 个本科专业,涵盖医、理、工、管、文等 5 大学科门类。中医诊断学在本学科研究领
域居国内领先水平。
小 F 居住在含浦校区,他想和东塘校区的同学小 L 聊天,为了保证沟通安全,他发明了一种加密方式,这
种加密方式是这样的:对于一个 01 串,小 F 会将其从左到右每 8 位分成一组,最后一组可能不足 8 位,
对每组进行逆序操作,即如果原来是 bLbL+1bL+2 · · · bR−1bR, 逆序之后变成 bRbR−1bR−2 · · · bL−1bL。现在
小 F 已经加密好了一个串,并且将其发给了小 L,你能帮助小 L 得到这串密文对应的原始信息吗?
输入
单组数据。
一行一个 01 串,代表加密后的字符串,串长度大于 0, 小于等于 100。
输出
一行字符串,代表加密后的字符串所对应的原始信。
样例输入 Copy
100010110011101
样例输出 Copy
110100011011100

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int min(int a,int b){
    if(a<b)
        return a;
    else
        return b;
}
int main(){
    char c[100];
    scanf("%s",&c);
    int length=strlen(c);
    for(int i=0;i<length;i+=8){
        for(int j=min(i+7,length-1);j>=i;--j)
            printf("%c",c[j]);
    }
    return 0;
}

B 最长公共子序列问题(LCS)之备忘录法

题目描述
使用备忘录法求解两个序列的最长公共子序列的长度。
输入
每组输入包括两行,每行包括一个字符串。
输出
两个序列的最长公共子序列的长度。
样例输入 Copy
ACBCDABD
ABDCABA
样例输出 Copy
5

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int c[100][100]={0};
int Max(int a,int b){
    if(a>=b)
        return a;
    else
        return b;
}
int Lcs(char x[],char y[],int i,int j){
    if(i<0||j<0)
        return 0;
    if(c[i][j]==0){
        if(x[i]==y[j])
            c[i][j]=Lcs(x,y,i-1,j-1)+1;
        else
            c[i][j]=Max(Lcs(x,y,i-1,j),Lcs(x,y,i,j-1));
    }
    return c[i][j];
}
int main(){
    char x[100],y[100];
    scanf("%s",&x);
    scanf("%s",&y);
    int p=strlen(x);
    int q=strlen(y);
    int sum=Lcs(x,y,p-1,q-1);
    printf("%d\n",sum);
}

C 最长公共子序列问题(LCS)之动态规划法

题目描述
使用动态规划算法求解两个序列的最长公共子序列的长度。
输入
每组输入包括两行,每行包括一个字符串。
输出
两个序列的最长公共子序列的长度。
样例输入 Copy
ACBCDABD
ABDCABA
样例输出 Copy
5

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int c[100][100]={0};
int Lcs(char x[],char y[],int i,int j){
    for(int m=1;m<i+1;m++){
        for(int n=1;n<j+1;n++){
            if(x[m-1]==y[n-1])
                c[m][n]=c[m-1][n-1]+1;
            else if(c[m-1][n]>=c[m][n-1])
                c[m][n]=c[m-1][n];
            else
                c[m][n]=c[m][n-1];
        }
    }
    return c[i][j];
}
int main(){
    char x[100],y[100];
    scanf("%s",&x);
    scanf("%s",&y);
    int p=strlen(x);
    int q=strlen(y);
    int sum=Lcs(x,y,p,q);
    printf("%d\n",sum);
}

D 最长公共子序列问题(LCS)-构造LCS

题目描述
使用动态规划算法求两个序列的最长公共子序列,需构造一条最长公共子序列。
输入
每组输入包括两行,每行包括一个字符串。
输出
两个字符序列的一条最长公共子序列。(输入已确保最长公共子序列的唯一性)
样例输入 Copy
acdbxx
ccdxx
样例输出 Copy
cdxx

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int c[100][100]={0};
int b[100][100]={0};
void Lcslength(char x[],char y[],int i,int j){
    for(int m=1;m<i+1;m++){
        for(int n=1;n<j+1;n++){
            if(x[m-1]==y[n-1]){
                c[m][n]=c[m-1][n-1]+1;
                b[m][n]=1;
            }
            else if(c[m-1][n]>=c[m][n-1]){
                c[m][n]=c[m-1][n];
                b[m][n]=2;
            }
            else{
                c[m][n]=c[m][n-1];
                b[m][n]=3;
            }
        }
    }
}
void Lcs(int i,int j,char x[]){
    if(i==0||j==0)
        return;
    if(b[i][j]==1){
        Lcs(i-1,j-1,x);
        printf("%c",x[i-1]);
    }
    else if(b[i][j]==2){
        Lcs(i-1,j,x);
    }
    else
        Lcs(i,j-1,x);
 
}
int main(){
    char x[100],y[100];
    scanf("%s",&x);
    scanf("%s",&y);
    int p=strlen(x);
    int q=strlen(y);
    Lcslength(x,y,p,q);
    Lcs(p,q,x);
}

E 牛牛的字符串

题目描述
牛牛有两个字符串(可能包含空格),他想找出其中最长的公共连续子串的长度,希望你能帮助他。例如:两个字符串分别为"abede"和"abgde",结果为2。
输入
每组数据包括两行,每行为一个字符串。
输出
输出最长的公共连续子串的长度。
样例输入 Copy
abede
abgde
样例输出 Copy
2

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int c[100][100]={0};
int Lcs(char x[],char y[],int i,int j){
    for(int m=1;m<=i;m++){
        for(int n=1;n<=j;n++){
            if(x[m-1]==y[n-1])
                c[m][n]=c[m-1][n-1]+1;
            else
                c[m][n]=0;
        }
    }
    int max=c[0][0];
    for(int ii=1;ii<=i;ii++){
        for(int jj=1;jj<=j;jj++){
            if(max<c[ii][jj]){
               max=c[ii][jj];
            }
        }
    }
    return max;
}
int main(){
    char x[100],y[100];
    scanf("%s",&x);
    scanf("%s",&y);
    int p=strlen(x);
    int q=strlen(y);
    int sum=Lcs(x,y,p,q);
    printf("%d\n",sum);
}

F 最大子段和

题目描述
给定n个整数(可能是负数)组成的序列a[1], a[2], a[3], …, a[n],求该序列的子段和如a[i]+a[i+1]+…+a[j]的最大值。
输入
每组输入包括两行,第一行为序列长度n,第二行为序列。
输出
输出字段和的最大值。
样例输入 Copy
5
-1 0 1 2 3
样例输出 Copy
6

#include <stdio.h>
#include <stdlib.h>
int a[100],b[100],n,max;
void solve()
{
    b[0]=a[0];
    max=b[0];
    for(int i=1; i<n; i++)
    {
        if(b[i-1]>0)
            b[i]=a[i]+b[i-1];
        else
            b[i]=a[i];
        if(b[i]>max)
            max=b[i];
    }
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        max=0;
        for(int i=0; i<n; i++)
            scanf("%d",&a[i]);
        solve();
        printf("%d\n",max);
    }
    return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值