【C++】每周一题——2024.3.3

题目

Cpp

【问题描述】

字符环(来源:NOI题库)。有两个由字符构成的环,请写一个程序,计算这两个字符环上最长公共字符串的长度。例如,字符串"ABCEFAGADEGKABUVKLM"的首尾连在一起,构成一个环;字符串"MADJKLUVKL"的首尾连在一起,构成另一个环;"UVKLMA"是这两个环的一个公共字符串。

【输入格式】

有两行,每行一个不包含空格的字符串,每行的字符串首尾相连即为一个环。

【输出格式】

一行,输出一个整数,表示这两个字符环上最长公共字符串的长度。

【输入样例】
ABCEFAGADEGKABUVKLM MADJKLUVKL

【输出样例】
6

【数据范围】

字符串长度不超过255


分析

就是找两个字符串的最大的连续交集 。只不过字符串首尾相连


思路

其实要考虑的只不过是最后一位的下一位是第一位 而已。这也很简单,直接将该字符串复制一份接到它后面即可。然后就可以循环找子集了。


代码

  1. 框架

    cpp 复制代码
    int main(){
    	return 0;
    }

  2. 输入字符串

    cpp 复制代码
    #include<cstdio>	//scanf()
    char a[256], b[256]; 
    int main(){
    	scanf("%s %s", &a, &b);
    	return 0;
    }

  3. 拼接字符串

    注意,不能直接用strcat()函数拼接

    cpp 复制代码
    #include<cstdio>	//scanf()
    #include<cstring>	//strcpy(), strcat(), memset()
    char a[256], b[256], c[256];
    int main(){
    	scanf("%s %s", &a, &b);
    	strcpy(c, a);
    	strcat(a, c);
    	memset(c, 0, sizeof(c));
    	strcpy(c, b);
    	strcat(b, c);
    	return 0;
    }

  4. 遍历字符串a的子集(遍历头和尾,并同时求出子集)。详见该文张2.5版解题思路

    cpp 复制代码
    #include<cstdio>	//scanf()
    #include<cstring>	//strcpy(), strcat(), memset(), strlen()
    char a[256], b[256], c[256];
    int l;
    int main(){
    	scanf("%s %s", &a, &b);
    	strcpy(c, a);
    	strcat(a, c);
    	memset(c, 0, sizeof(c));
    	strcpy(c, b);
    	strcat(b, c);
    	l=strlen(a);
    	for(int i=0; i<l; i++){
    		memset(c, 0, sizeof(c));
    		for(int j=0; j<l-i; j++){
    			c[j]=a[i+j];
    		}
    	}
    	return 0;
    }

  5. 已经求出了一个字符串的子集,现在直接判断该子集是否同时存在于另一个字符串中。如果存在,就将该子集的长度比较存入变量中。

    cpp 复制代码
    #include<cstdio>	//scanf()
    #include<cstring>	//strcpy(), strcat(), memset(), strlen(), strstr()
    #include<cmath>		//fmax()
    char a[256], b[256], c[256];
    int l, ans;
    int main(){
    	scanf("%s %s", &a, &b);
    	strcpy(c, a);
    	strcat(a, c);
    	memset(c, 0, sizeof(c));
    	strcpy(c, b);
    	strcat(b, c);
    	l=strlen(a);
    	for(int i=0; i<l; i++){
    		memset(c, 0, sizeof(c));
    		for(int j=0; j<l-i; j++){
    			c[j]=a[i+j];
    			if(strstr(b, c)!=NULL){
    				ans=fmax(ans, j+1);
    			}
    		}
    	}
    	return 0;
    }

  6. 最后,输出变量即可。

    cpp 复制代码
    #include<cstdio>	//scanf(), printf()
    #include<cstring>	//strcpy(), strcat(), memset(), strlen(), strstr()
    #include<cmath>		//fmax()
    char a[256], b[256], c[256];
    int l, ans;
    int main(){
    	scanf("%s %s", &a, &b);
    	strcpy(c, a);
    	strcat(a, c);
    	memset(c, 0, sizeof(c));
    	strcpy(c, b);
    	strcat(b, c);
    	l=strlen(a);
    	for(int i=0; i<l; i++){
    		memset(c, 0, sizeof(c));
    		for(int j=0; j<l-i; j++){
    			c[j]=a[i+j];
    			if(strstr(b, c)!=NULL){
    				ans=fmax(ans, j+1);
    			}
    		}
    	}
    	printf("%d", ans);
    	return 0;
    }


答案

cpp 复制代码
#include<cstdio>
#include<cstring>
#include<cmath>
char a[256], b[256], c[256];
int l, ans;
int main(){
	scanf("%s %s", &a, &b);
	strcpy(c, a);
	strcat(a, c);
	memset(c, 0, sizeof(c));
	strcpy(c, b);
	strcat(b, c);
	l=strlen(a);
	for(int i=0; i<l; i++){
		memset(c, 0, sizeof(c));
		for(int j=0; j<l-i; j++){
			c[j]=a[i+j];
			if(strstr(b, c)!=NULL){
				ans=fmax(ans, j+1);
			}
		}
	}
	printf("%d", ans);
	return 0;
}

相关推荐
写代码的小球1 小时前
求模运算符c
算法
tan180°4 小时前
MySQL表的操作(3)
linux·数据库·c++·vscode·后端·mysql
大千AI助手5 小时前
DTW模版匹配:弹性对齐的时间序列相似度度量算法
人工智能·算法·机器学习·数据挖掘·模版匹配·dtw模版匹配
彭祥.6 小时前
Jetson边缘计算主板:Ubuntu 环境配置 CUDA 与 cudNN 推理环境 + OpenCV 与 C++ 进行目标分类
c++·opencv·分类
lzb_kkk6 小时前
【C++】C++四种类型转换操作符详解
开发语言·c++·windows·1024程序员节
YuTaoShao6 小时前
【LeetCode 热题 100】48. 旋转图像——转置+水平翻转
java·算法·leetcode·职场和发展
生态遥感监测笔记6 小时前
GEE利用已有土地利用数据选取样本点并进行分类
人工智能·算法·机器学习·分类·数据挖掘
Tony沈哲7 小时前
macOS 上为 Compose Desktop 构建跨架构图像处理 dylib:OpenCV + libraw + libheif 实践指南
opencv·算法
刘海东刘海东7 小时前
结构型智能科技的关键可行性——信息型智能向结构型智能的转变(修改提纲)
人工智能·算法·机器学习