题意:
给定两个长度相同且不超过100的字符串,判断是否能把其中一个字符串的各个字母重排,然后对26个字母做一个一一映射,使得两个字符串相同。例如,JWPUDJSTVP重排后可以得到WJDUPSJPVT,然后把每个字母映射到它前一个字母(B->A,C->B,…,Z->Y,A->Z),得到VICTORIOUS。输入两个字符串,输出YES或者NO。
思路:
一开始读完题之后就想着开几个map来映射字母,然后统计个数,如果原文中的一个字母和密文中的一个字母个数相等的话且之前没有被选择过,就作为它的密文字母。
时间复杂度为O(n^2),n为字符串的长度。提交了之后居然TLE?就离谱。然后紫书上的正解是用int数组映射之后然后排序,时间复杂度应该是nlogn。下午把正解更新
代码1 一开始的思路
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N = 110; 4 char s1[N],s2[N]; 5 map<char,int>mp1; 6 map<char,int>mp2; 7 map<char,bool>is_selected; 8 int n; 9 bool solve() 10 { 11 int tot=0; 12 for(map<char,int>::iterator it1=mp1.begin();it1!=mp1.end();it1++) 13 { 14 int cnt1=it1->second; 15 for(map<char,int>::iterator it2=mp2.begin();it2!=mp2.end();it2++) 16 { 17 int cnt2=it2->second; 18 char c=it2->first; 19 if(cnt1==cnt2&&is_selected[c]==false) 20 { 21 is_selected[c]=true; 22 tot++; 23 break; 24 } 25 } 26 } 27 if(tot==mp1.size())return true; 28 else return false; 29 } 30 31 int main() 32 { 33 while(scanf("%s%s",s1,s2)) 34 { 35 mp1.clear(),mp2.clear(); 36 is_selected.clear(); 37 n=strlen(s1); 38 for(int i=0;i<n;i++) 39 { 40 mp1[s1[i]]++; 41 mp2[s2[i]]++; 42 is_selected[s2[i]]=false; 43 } 44 bool res=solve(); 45 if(res==true)puts("YES"); 46 else puts("NO"); 47 } 48 return 0; 49 }