poj2159

来源:互联网 发布:.club域名价值 编辑:程序博客网 时间:2024/05/19 17:23

摘要:给定一个大写的字符串,如果该字符串能够通过某种置换以及排列成为另外一个字符串,则称第二个是第一个字符串的加密.比如第二个字符串会通过每一个单词变到字母表中的下一个单词(这种变换每个单词都不一样,不同的单词不能变到同一个单词)然后相互交换位置成为第一个字符串.
J可以变成W(字母表中的下一个),但是不一定会变成W,可以是任何一个字母,也可以是本身.这是非常容易搞错的.想清楚这个就很简单了,相同的单词一定会变成另外相同的单词,经过排列只是位置变了,但是频率不变.因此两个字符串的频率一致就是关键.可以采用一个数组记录频率,然后将数组进行排序,在比较两个数组是否完全一致.这是常规做法.这是O(NLogN)的效率.

还有一种做法是再次记录频率,这次记录第一次频率出现的频率,比如第一次有5个不同的字母,表现在记录上就是由5个A[x] = 1;表现在第二次的记录上就是B[1] = 5;它表示有5个不同的字母.B[index] = m表示存在{index个字母}{index个字母}{index个字母}…{index个字母}一共m个集合.这样也可以判断频率的分布.这里需要注意的是由可能有同一个字母出现100次,所以第二个记录的数组要求空间很大,这种方法的算法效率是O(N),但是空间要求更多,而且在N较小时由于读入数据初始化等原因可能消耗远多于第一种的时间.

#include <stdio.h>#include <iostream>using namespace std;int main(){    int i = 0;    bool ispossible = true;//标记最后结果    char s1[101] = {'0'},s2[101] = {'0'};    int count1[26] = {0},count2[26] = {0};//用来作为统计两个字符串的字母数量    int count3[101] = {0},count4[101] = {0};    i = 0;    cin>>s1;    cin>>s2;    while(s2[i]!='\0'&&s1[i]!='\0')    {    count1[int(s1[i])-'A']++;    count2[int(s2[i])-'A']++;     i++;    }    if(s1[i]!=s2[i])        ispossible = false;    else    {    for(i = 0;i<=25;)    {        count3[count1[i]]++;        count4[count2[i]]++;        i++;    }    for(i = 1;i<=100;i++)    {        if(count3[i] != count4[i])        {            ispossible = false;            break;        }    }    }    if(ispossible)        cout<<"YES\n";    else        cout<<"NO\n";    return 0;}
0 0