1528;匹配字符串(平顶山学院)
2016-09-06 16:22
197 查看
1528: 匹配字符串
题目描述
2015 年广东工业大学ACM校赛要来~\(≧▽≦)/~辣辣辣,作为校赛的出题人之一,GG想出了一道水题来考考大家。相信小伙伴们都学过字符串匹配,于是字符 串匹配的水题就诞生辣!GG给出了一段长度为N的大写字母序列,现在他要你修改这一段字母序列,使得这段字母序列上最前面的K个字母组成的序列与最后面的 K个字母组成的序列一一匹配。
例如对于序列“ATUUUUAC”和K = 2,可以通过将第二个字母修改为“C”,使得最前面的两个字母与最后面的两个字母都为“AC”,当然 还存在其他的修改方法,现在GG要求你求出要使字符串匹配至少需要修改多少个字母。
输入
有T组数据输入。(T <= 100)
每组数据只有两行,第一行为一个字符串,第二行为一个正整数K,字符串的长度不会超过1000,且至少为1。(1 <= K <= N)。
输出
对于每组数据输出至少需要修改的字母数量
样例输入
2
ATUUUUAC
2
ATACGTCT
6
样例输出
1
3
题目代码:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int main()
{
int num,len,m,i,b[26],j;
char s[1000];
scanf("%d",&num);
while(num--)
{
int mmin=0;
getchar(); //用于接收输入num后的那个空格
scanf("%s",s); //输入字符串
scanf("%d",&m); //前m个字符与后m个字符相同
len=strlen(s);//测字符串长度
if(m<=len/2)//如果m小于或等于字符串长度的一半的话,那么我只用比较前m个与后m个有几个字符不同,就是答案
{
for(i=0;i<m;i++)
if(s[i]!=s[len+i-m])
mmin++;
printf("%d\n",mmin);
}
else//这个比较麻烦,因为如果m>len/2时,许多字母是绑定在一起的
{
int t=len-m;
for(i=0;i<m;i++)//前m个字符
{
j=i;
int sum1=0;
memset(b,0,sizeof(b)); //每从一个字母开始,都将b数组置为0,代表从这个字母开始走,模拟出一条路
while(1)
{
if(s[j]!='1')//如果我这个位置没有走过
{
b[s[j]-'A']++; //选择一条路,并统计这条路中遇到的各个字母的个数
s[j]='1'; //标记为1,代表该位置考虑过了
sum1++;//与第i个字母绑定在一起的字母总个数
}
j=j+t; //下一个与第i个字母相关联的字母
if(j>len-1)//如果超过字符串的长度,代表所有与第i个字母相关联的字母都找完了
break;
}
sort(b,b+26);//排序,求与第I个字母绑定的所有字母中那个字母最多
mmin=mmin+(sum1-b[25]); //就等于与第I个字母绑定的字母个数减去某个字母个数最多,就是最少的修改次数,
}
printf("%d\n",mmin);
}
}
return 0;
}
0 1 2 3 4 5 6 7
A T A C G T C T
A T A C G T C T
0 1 2 3 4 5 6 7
按照循环
当i=0时,
要修改的为0 2 4 6 A A G C这条路的长度为4,字母A最多,所以不修改字母A,将其他两个字母修改为字母A,需要路的长度-某个字母个数的最大值。
当i=1时
要修改的为1 3 5 7他们是相互绑定的。T C T T,字母T最多,所以将其他与字母T不一样的字母都变为T,修改的次数最少,这条路的长度为4
字母T最多是3个,那么要修改有4-3=1;
当i=2时
2 4 6 都已经考虑过了
当i=3时
3 5 7绑定也都考虑过了
........
题目描述
2015 年广东工业大学ACM校赛要来~\(≧▽≦)/~辣辣辣,作为校赛的出题人之一,GG想出了一道水题来考考大家。相信小伙伴们都学过字符串匹配,于是字符 串匹配的水题就诞生辣!GG给出了一段长度为N的大写字母序列,现在他要你修改这一段字母序列,使得这段字母序列上最前面的K个字母组成的序列与最后面的 K个字母组成的序列一一匹配。
例如对于序列“ATUUUUAC”和K = 2,可以通过将第二个字母修改为“C”,使得最前面的两个字母与最后面的两个字母都为“AC”,当然 还存在其他的修改方法,现在GG要求你求出要使字符串匹配至少需要修改多少个字母。
输入
有T组数据输入。(T <= 100)
每组数据只有两行,第一行为一个字符串,第二行为一个正整数K,字符串的长度不会超过1000,且至少为1。(1 <= K <= N)。
输出
对于每组数据输出至少需要修改的字母数量
样例输入
2
ATUUUUAC
2
ATACGTCT
6
样例输出
1
3
题目代码:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int main()
{
int num,len,m,i,b[26],j;
char s[1000];
scanf("%d",&num);
while(num--)
{
int mmin=0;
getchar(); //用于接收输入num后的那个空格
scanf("%s",s); //输入字符串
scanf("%d",&m); //前m个字符与后m个字符相同
len=strlen(s);//测字符串长度
if(m<=len/2)//如果m小于或等于字符串长度的一半的话,那么我只用比较前m个与后m个有几个字符不同,就是答案
{
for(i=0;i<m;i++)
if(s[i]!=s[len+i-m])
mmin++;
printf("%d\n",mmin);
}
else//这个比较麻烦,因为如果m>len/2时,许多字母是绑定在一起的
{
int t=len-m;
for(i=0;i<m;i++)//前m个字符
{
j=i;
int sum1=0;
memset(b,0,sizeof(b)); //每从一个字母开始,都将b数组置为0,代表从这个字母开始走,模拟出一条路
while(1)
{
if(s[j]!='1')//如果我这个位置没有走过
{
b[s[j]-'A']++; //选择一条路,并统计这条路中遇到的各个字母的个数
s[j]='1'; //标记为1,代表该位置考虑过了
sum1++;//与第i个字母绑定在一起的字母总个数
}
j=j+t; //下一个与第i个字母相关联的字母
if(j>len-1)//如果超过字符串的长度,代表所有与第i个字母相关联的字母都找完了
break;
}
sort(b,b+26);//排序,求与第I个字母绑定的所有字母中那个字母最多
mmin=mmin+(sum1-b[25]); //就等于与第I个字母绑定的字母个数减去某个字母个数最多,就是最少的修改次数,
}
printf("%d\n",mmin);
}
}
return 0;
}
0 1 2 3 4 5 6 7
A T A C G T C T
A T A C G T C T
0 1 2 3 4 5 6 7
按照循环
当i=0时,
要修改的为0 2 4 6 A A G C这条路的长度为4,字母A最多,所以不修改字母A,将其他两个字母修改为字母A,需要路的长度-某个字母个数的最大值。
当i=1时
要修改的为1 3 5 7他们是相互绑定的。T C T T,字母T最多,所以将其他与字母T不一样的字母都变为T,修改的次数最少,这条路的长度为4
字母T最多是3个,那么要修改有4-3=1;
当i=2时
2 4 6 都已经考虑过了
当i=3时
3 5 7绑定也都考虑过了
........
相关文章推荐
- chrome jsonView插件安装
- 信息传播
- 网络流各种题型应用及解决方法
- eclipse汉化方法
- JQuery window、document、 body
- 深入AsyncTask
- mac版eclipse 转到windows eclipse后问题
- Learnning Dlib(六) Speeding up Dlib’s Facial Landmark Detector
- caffe中网络结构参数详解
- Java中字符串常量相加
- JAVA基础面试及笔试题
- Nginx初探之二
- 触发器同步
- 支付宝pc端支付接入PHP实现
- swift-sharesdk集成微信、Facebook第三方登录
- 使用栈解决迷宫问题
- libvirt依赖的库
- Spring BeanUtils.copyProperties和apache commons-beanutils
- BroadcastReceiver学习之路(01)之普通广播及广播简介
- 使用北通手柄控制turtlesim运动