codeforces 883F. Lost in Transliteration (字符串处理)

传送门codeforces 883F



题目大意

字符 u 和 oo 等价,字符 h 和 kh等价,问给出的 n 个字符串中不同的串有多少个。注意 kkkkh 是和 h 等价的,因为可以通过多步替换得到, ooo 的情况可以等价为 ou 或 uo。



思路

大体思路是先按照规则把串替换,然后看有多少个不同的串。在判断有多少不同串的时候可以先排序,如果相邻两个串不同则结果 +1. 由于用到字符串的排序,这里用的是 string 类型(char数组是无法用 sort 函数直接排序的)。


对于 h 和 kh 等价,我们可以找到字符串中的 h,把 h 之前连续的 k 都去掉。而对于 u 和 oo 等价,因为 ooo 有 2 种情况与之等价,所以我们考虑把字符串中所有的 u 换成 oo。


排序的时候可以用 s<t 直接比较 string 类型的字符串 s 和 t 的大小。用 s != t 判断是否不等。



PS

1.在替换的时候无法直接对 s[i]=t[j] 复制字符……我也不知道为什么……所以只好先用 char 数组修改,在排序之前再转成 string 类型。(又从网上看了下大神的代码,也可以直接用string,见代码 two)


2.将 kkkkkkkh 中 h 之前连续的 k 去除的时候,我的方法是将 k 变为空格。



代码


one:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;

int cmp(string a,string b)
{ //比较字符串大小 
	return a<b;
}

int main()
{
	int i,j,k,n,len,tol;
	char t[42],s[404][42];
	string str[404];
	while(cin>>n)
	{
		for(i=0;i<n;i++)
		{
			cin>>t;
			len=strlen(t);
			for(j=1;j<len;j++)
			{
				if(t[j]=='h')
				{ //去除 h 前面连续的 k 
					k=j-1;
					while(k>=0&&t[k]=='k') t[k--]=' '; //换成空格 
				}
			}
			tol=0;
			for(j=0;j<len;j++)
				if(t[j]!=' ')
				{ //将 t 存储到 s[i] 
					if(t[j]=='u')
					{ //如果是 u 则换为 oo 
						s[i][tol++]='o';
						s[i][tol++]='o';
					}
					else s[i][tol++]=t[j];
				}					
			s[i][tol]='\0'; //结束标志 
		}
		for(i=0;i<n;i++) //将 char数组转换成 string类型 
			str[i]=s[i];
		sort(str,str+n,cmp); //排序 
		//cout<<endl;
		//for(i=0;i<n;i++) cout<<str[i]<<endl;
		int ans=1;
		for(i=1;i<n;i++) //如果相邻字符串不同,则结果+1 
			if(str[i]!=str[i-1])
				ans++;
		cout<<ans<<endl;
	}
	return 0;
}


two:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;

int cmp(string a,string b)
{ //比较字符串大小 
	return a<b;
}

int main()
{
	int i,j,k,n,len;
	string t,s[404];
	while(cin>>n)
	{
		for(i=0;i<n;i++)
		{
			cin>>t;
			len=t.length();
			for(j=1;j<len;j++)
			{
				if(t[j]=='h')
				{ //去除 h 前面连续的 k 
					k=j-1;
					while(k>=0&&t[k]=='k') t[k--]=' '; //换成空格 
				}
			}
			s[i]="";
			for(j=0;j<len;j++)
				if(t[j]!=' ')
				{ //将 t 存储到 s[i] 
					if(t[j]=='u') s[i]+="oo"; //如果是 u 则换为 oo 
					else s[i]+=t[j];
				}					
			s[i]+='\0'; //结束标志
		}
		sort(s,s+n,cmp); //排序 
		int ans=1;
		for(i=1;i<n;i++) //如果相邻字符串不同,则结果+1 
			if(s[i]!=s[i-1])
				ans++;
		cout<<ans<<endl;
	}
	return 0;
}



  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值