牛客网 回文解码 C语言

问题描述:

现在有一个字符串,你要对这个字符串进行 n 次操作,每次操作给出两个数字:(p, l) 表示当前字符串中从下标为 p 的字符开始的长度为 l 的一个子串。你要将这个子串左右翻转后插在这个子串原来位置的正后方,求最后得到的字符串是什么。字符串的下标是从 0 开始的,你可以从样例中得到更多信息。

输入描述:

每组测试用例仅包含一组数据,每组数据第一行为原字符串,长度不超过 10 ,仅包含大小写字符与数字。接下来会有一个数字 n 表示有 n 个操作,再接下来有 n 行,每行两个整数,表示每次操作的(p , l)。
保证输入的操作一定合法,最后得到的字符串长度不超过 1000。

输出描述:

输出一个字符串代表最后得到的字符串。

示例1

输入
ab
2
0 2
1 3

输出

abbaabb

c语言代码

#include<stdio.h>
#include<string.h>
int main(){
    char a[500];
    int start[50],length[50]; 
    int i,j,r;
    int p,q;
    int num; 
    int x;   
    //printf("请输入字符串:");
    scanf("%s",a);
    
    //printf("请输入操作次数:");
    scanf("%d",&num);
    
    //printf("请输入操作起始和长度:\n");
    for(i=0;i<num;i++){
    	scanf("%d%d",&start[i],&length[i]);
    }
     
    for(i=0;i<num;i++){    	
    	x= strlen(a);    	
    	p=start[i]+length[i]-1;
    	q=p+1; 
    	 		    		
			for(j=0;j<length[i];j++){ 
		 		if(q!=x){
		 		for(r=x;r>q;r--){
				 	a[r]=a[r-1];
				 }	
		 		}				 			
 				a[q]=a[p];	
    			q++;
				p--;
				x++; 
    		} 
    	
    	
    	
    	a[x]='\0';    	
    }
    printf("%s",a);
}


(上机可运行,渣作勿喷。。)

PTA(Programming Teaching Assistant)最小回文数是一个常见的算法问题,其目标是通过给定的字符串,经过最少次数的插入操作,使得字符串变成一个回文字符串回文字符串是指正读和反读都相同的字符串。 解决这个问题的基本思路是通过动态规划或贪心算法,遍历字符串的同时检查每个字符的位置,保证从左到右和从右到左的字符是匹配的。如果遇到不匹配的情况,就需要插入字符,使得整个字符串成为回文串。通常,我们可以选择在左边或者右边插入字符,但是为了保证插入次数最少,我们需要选择一个更合理的位置进行插入。 具体来说,可以使用以下步骤: 1. 初始化一个二维数组 `dp`,其中 `dp[i][j]` 表示字符串从第 `i` 个字符到第 `j` 个字符变为回文串需要的最小插入次数。 2. 对于长度为 `n` 的字符串,遍历所有可能的子串长度,即对每个 `l` 从 `2` 到 `n`,再对每个子串的起始位置 `i` 从 `0` 到 `n-l`,计算 `dp[i][i+l-1]`。 3. 对于子串 `str[i...j]`: - 如果 `str[i] == str[j]`,则 `dp[i][j] = dp[i+1][j-1]`,因为两端的字符已经匹配,不需要额外操作。 - 如果 `str[i] != str[j]`,需要插入一个字符来匹配两端,`dp[i][j] = min(dp[i+1][j], dp[i][j-1]) + 1`,分别表示在左端或右端插入字符后,剩下的子串需要的最小插入次数加一。 4. 最终结果存储在 `dp[0][n-1]` 中,即整个字符串变为回文串需要的最小插入次数。 5. 通过回溯 `dp` 数组,可以找到具体的插入位置。 这里提供一个简化的代码示例,用于说明思路,并非完整的代码实现: ```c #include <stdio.h> #include <string.h> int minInsertions(char *str) { int n = strlen(str); int dp[n][n]; // 初始化动态规划数组 for (int i = 0; i < n; i++) { dp[i][i] = 0; // 单个字符的子串已经是回文串,不需要插入 } // 动态规划填表 for (int l = 2; l <= n; l++) { // 子串长度从2开始 for (int i = 0; i <= n - l; i++) { // 子串起始位置 int j = i + l - 1; // 子串结束位置 if (str[i] == str[j]) { dp[i][j] = dp[i + 1][j - 1]; } else { dp[i][j] = fmin(dp[i + 1][j], dp[i][j - 1]) + 1; } } } return dp[0][n - 1]; // 整个字符串变为回文串需要的最小插入次数 } int main() { char str[] = "abca"; printf("Minimum insertions to make string palindrome: %d\n", minInsertions(str)); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值