字符串转换-北邮OJ90

地址:http://10.105.242.80/problem/p/90/

90. 字符串转换

时间限制 1000 ms 内存限制 65536 KB

题目描述

我们将仅由若干个同一小写字母构成的字符串称之为简单串,例如"aaaa"是一个简单串,而"abcd"则不是简单串。现在给你一个仅由小写字母组成的字符串,你需要用最小的花费,将其转换成一个简单串。 花费的计算规则如下:将a到z这26个小写字母从左到右排成一排,则每个字母都有左右两个邻居,我们认为a的左邻居是z,z的右邻居是a。一个字母只能转换成其相邻的字母,转换的花费为1。一个字母可以进行多次转换,例如将a转换成d,可以进行如下的步骤: a->b->c->d,花费为3。字符串的转换花费为所有字母转换花费之和。例如将字符串"abbbz"转换成简单串的最小花费为3,转换后的结果为"bbbbb"。

输入格式

第一行一个整数T(T≤100),表示测试数据的组数。 每组测试数据只有一行,为仅含小写字母的字符串,字符串长度不超过1000。

输出格式

对于每一组数据,输出一个整数,表示将字符串转换成简单串的最小花费。

输入样例

2
abbba
abbac

输出样例

2
3
/*
90. 字符串转换
时间限制 1000 ms 内存限制 65536 KB
题目描述

我们将仅由若干个同一小写字母构成的字符串称之为简单串,例如"aaaa"是一个简单串,而"abcd"则不是简单串。现在给你一个仅由小写字母组成的字符串,你需要用最小的花费,将其转换成一个简单串。 花费的计算规则如下:将a到z这26个小写字母从左到右排成一排,则每个字母都有左右两个邻居,我们认为a的左邻居是z,z的右邻居是a。一个字母只能转换成其相邻的字母,转换的花费为1。一个字母可以进行多次转换,例如将a转换成d,可以进行如下的步骤: a->b->c->d,花费为3。字符串的转换花费为所有字母转换花费之和。例如将字符串"abbbz"转换成简单串的最小花费为3,转换后的结果为"bbbbb"。
输入格式

第一行一个整数T(T≤100),表示测试数据的组数。 每组测试数据只有一行,为仅含小写字母的字符串,字符串长度不超过1000。
输出格式

对于每一组数据,输出一个整数,表示将字符串转换成简单串的最小花费。
输入样例

2
abbba
abbac

输出样例

2
3
Project:
Date:    2019/02/26
Author:  Frank Yu
*/
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
#include<set>
#include<list>
#include<vector>
#include<map>
#include<iterator>
#include<algorithm>
#include<iostream>
using namespace std;
//两个字母最小花费
int minfee(char c1,char c2)
{
	int fee1,fee2;
	if(c1>c2)
	{
		fee1=c1-c2;
		fee2='z'-c1+c2-'a'+1;
		//cout<<fee1<<" "<<fee2<<endl;
		return min(fee1,fee2);
	}
	else
	{
		fee1=c2-c1;
		fee2='z'-c2+c1-'a'+1;
		//cout<<fee1<<" "<<fee2<<endl;
		return min(fee1,fee2);
	}
} 
//主函数
 int main()
{
 int T,sum,min;//数据组数 字符串某个转换字母的总花费 字符串的最小花费	
 char c1,c2;
 string ss;
 int count[26];//对应字母出现的次数
 bool flag[26];//标记当前转换字母
 cin>>T;
 while(T--)
 {
 	memset(count,0,sizeof(count));     //初始化统计数组 
 	for(int i=0;i<26;i++)flag[i]=false;//初始化标记数组
	min=9999999;                             //该字符串的最小花费 
 	cin>>ss;
 	for(int i=0;i<ss.length();i++)
	 {
		count[ss[i]-'a']++;//统计次数	 
	 } 
	for(int j=0;j<26;j++)  //遍历字符串每个字母,作为待转换字母 
	{
		if(count[j]!=0)//该字母在字符串中
		{
	      flag[j]=true;
	      sum=0;       //统计该字符串转换成该字母的最小花费 
		  for(int k=0;k<26;k++)//将其他字母转换为该字母 
		  {
		  	if(count[k]!=0&&!flag[k])//k对应字母在字符串中,且不是待转换字母 
		  	{
		  		//char a='a'+j;
		  		//char b='a'+k;
		  		//cout<<a<<" "<<b<<" ";
		  		sum=sum+minfee('a'+j,'a'+k)*count[k];//计算将k对应字母转换为j对应字母的花费,注意k对应字母的个数 
		  	}
		  }
		  if(sum<min)min=sum;
		  flag[j]=false;		
		}			
	}
	cout<<min<<endl;
 }
 return 0;
}

更多数据结构与算法实现:数据结构(严蔚敏版)与算法的实现(含全部代码)

有问题请下方评论,转载请注明出处,并附有原文链接,谢谢!如有侵权,请及时联系。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lady_killer9

感谢您的打赏,我会加倍努力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值