B. AquaMoon and Stolen String
题意:
给定t组n,m
( t组n*m的总和 <= 1e5 )
接下来n行
n个长度为m的字符串
对于每一对字符串,假设为s[i]和s[j]
你都可以选择一些位置(至少1个,最多m个)
并在所选位置交换这一对的两个字符串中的字母。
即swap(s[i][k],s[j][k])
[ 1 <= i <= n , 1 <= j <= n , 1 <= k <= m ]
接下来n-1行
n-1个长度为m的字符串
问你
一定可以进行一些交换
使得这n-1个字符串等于
一开始给的n个字符串中的其中n-1个
并且输出剩下的那一个字符串
思路:
个人感觉这题理解题意是其一
那么考虑一下交换
只在不同对之间的不同位置交换
即swap(s[i][k],s[j][k]) [ 1 <= i <= n , 1 <= j <= n , 1 <= k <= n ]
即只有列之间的字母交换
但是列之间不管怎么交换
每一列对应的字母个数是不变的
所以最后的答案等于
每一列前n个字符串
和最后n-1个字符串作比较
所缺少的那一个字符相加
考虑一下一共26个字母
对每一列统计字母个数
一共n行,m列
用map方便统计
所以总体时间复杂度为 n * m * log26 + m * 26 * log26
时间复杂度:O n
#include<bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define re register int
#define pll pair<int,int>
#define x first
#define y second
#define sf(x) scanf("%d",&x)
#define sfl(x) scanf("%lld",&x)
typedef long long ll ;
using namespace std;
const int N = 1e5 + 10 , M = 1010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;
int n , m ;
map<char,int> q1[N] , q2[N] ;
int main()
{
int t ;
cin >> t ;
while(t--)
{
cin >> n >> m ;
fer(i,1,m) q1[i].clear() , q2[i].clear() ;
fer(i,1,n)
{
fer(j,1,m)
{
char x ;
cin >> x ;
q1[j][x] ++ ; // j这列x的字母个数++
}
}
fer(i,1,n-1)
{
fer(j,1,m)
{
char x ;
cin >> x ;
q2[j][x] ++ ; // j这列x的字母个数++
}
}
string res = "" ;
for(int i = 1 ; i <= m ; i ++)
{
for(char j = 'a' ; j <= 'z' ; j ++)
{
if(q1[i][j] - q2[i][j] == 1)
{
res += j ;
break ;
}
}
}
cout << res << "\n" ;
}
return 0;
}