被 自 己 蠢 哭 了 都 被自己蠢哭了都

看 数 据 范 围 明 显 只 能 枚 举 两 个 字 符 串 看数据范围明显只能枚举两个字符串

可 以 根 据 枚 举 的 两 个 推 算 出 第 三 个 字 符 串 可以根据枚举的两个推算出第三个字符串

因 为 总 共 只 有 三 种 选 法 , 答 案 是 唯 一 的 因为总共只有三种选法,答案是唯一的 ,

至 于 判 断 第 三 个 字 符 串 是 否 存 在 至于判断第三个字符串是否存在

s e t , m a p 或 者 转 化 为 数 字 都 可 以 啦 ! set,map或者转化为数字都可以啦! set,map!

代 码 里 是 用 的 字 典 树 代码里是用的字典树

#include <bits/stdc++.h>
using namespace std;
const int maxn=1509;
int tire[maxn*30][27],ans;
int n,m,top,isok[maxn*30];
string a[maxn];
void insert(string s)
{
	int now=0;
	for(int i=0,l=s.length();i<l;i++)
	{
		int k=s[i]-'A';
		if(!tire[now][k])	tire[now][k]=++top;
		now=tire[now][k];
	}
	isok[now]=1;
}
bool ask(string s)
{
	int now=0;
	for(int i=0,l=s.length();i<l;i++)
	{
		int k=s[i]-'A';
		if(!tire[now][k])	return false;
		now=tire[now][k];
	}
	return isok[now];
}
char find(char q,char w)
{
	if(q!='S'&&w!='S')	return 'S';
	else if(q!='E'&&w!='E')	return 'E';
	else	return 'T';
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)	cin>>a[i],insert(a[i]);
	for(int i=1;i<=n;i++)
	for(int j=i+1;j<=n;j++)
	{
		string temp="";
		for(int q=0;q<m;q++)
		{
			if(a[i][q]==a[j][q])	temp+=a[i][q];
			else	temp+=find(a[i][q],a[j][q]);
		}
		if(ask(temp))	ans++;
	}
	cout<<ans/3;
}