题目:给定两个字符串A,B。我们可以改变A中任意数量相同的字符x变成字符y(必须满足y > x),我们能否把A变成B,可以的话最少几次,不可以输出‘-1’。
思路:看了所有样例后,再通过样例1可以想到一个方法。我们有一个矩阵app['a'~'t']['a'~'t']记录A与B的对应关系,例如:
A:aab
B: bcc
则我们记录app['a']['b'] = 1, app['a']['c'] = 1, app['b']['c'] = 1,这样我们就有了AB的关系矩阵。然后我们想到,如果在app['a']['a'~'t']中第一个存在的关系是app['a'][x] = 1,则说明'a'对应的其他字符一定大于x,不如我们贪心的把其他'a'对应的关系都变成app[x][y],y是满足app['a'][y] = 1的字符,这样就是一个理想的解决方法(想到的时候感觉有点玄乎但感觉也对)。
补:写完题目后看其他人的写法,发现可以并查集。。。好神奇
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <queue> 5 #include <string> 6 #include <vector> 7 #include <cmath> 8 #include <stack> 9 10 using namespace std; 11 12 #define ll long long 13 #define pb push_back 14 #define fi first 15 #define se second 16 17 const int N = 30; 18 int app[30][30]; 19 20 void solve() 21 { 22 int T; 23 cin >> T; 24 while(T--){ 25 for(int i = 0; i <= 27; ++i) 26 for(int j = 0; j <= 27; ++j) 27 app[i][j] = 0; 28 29 int n, ok = 1; 30 string A, B; 31 cin >> n >> A >> B; 32 for(int i = 0; i < n; ++i){ 33 if(A[i] > B[i]){ 34 ok = 0; 35 break; 36 } 37 if(A[i] < B[i]) app[A[i] - 'a'][B[i] - 'a'] = 1; 38 } 39 40 int cnt = 0; 41 for(int i = 0; i <= 26; ++i){ 42 int s = -1; 43 for(int j = 0; j <= 26; ++j){ 44 if(i == j) continue; 45 if(app[i][j]){ 46 cnt++; 47 s = j;// a->b; 48 break; 49 } 50 } 51 //改变其他的a->的关系 52 if(s == -1) continue; 53 for(int k = s + 1; k <= 26; ++k){ 54 if(app[i][k]) app[s][k] = 1; 55 } 56 } 57 58 //cout << "ans = "; 59 if(ok) cout << cnt << endl; 60 else cout << "-1" << endl; 61 } 62 63 64 65 } 66 67 int main() 68 { 69 ios::sync_with_stdio(false); 70 cin.tie(0); 71 cout.tie(0); 72 73 solve(); 74 75 return 0; 76 }