CF152C Pocket Book

题面翻译

给出 n 个长度为 m 的字符串,定义一次操作(i , j , k)表示可以按任意选取1 <= i < j <= n ,1 <= k <= m ,使得编号为 i , j的两个字符串的长度为 k 的前缀互换;问任意多次操作后能得到的不同字符串的最大数量。
你可以将这 n 个字符串看为一个集合,然后将每一次操作后新产生的字符串加入到这个集合中,众所周知集合是满足互异性的,即集合内的字符串不能有相同。答案相当于经过任意多次操作后,集合所包含的最多的元素个数是多少

题目描述

One day little Vasya found mom’s pocket book. The book had $ n $ names of her friends and unusually enough, each name was exactly $ m $ letters long. Let’s number the names from $ 1 $ to $ n $ in the order in which they are written.

As mom wasn’t home, Vasya decided to play with names: he chose three integers $ i $ , $ j $ , $ k $ ( $ 1<=i<j<=n $ , $ 1<=k<=m $ ), then he took names number $ i $ and $ j $ and swapped their prefixes of length $ k $ . For example, if we take names “CBDAD” and “AABRD” and swap their prefixes with the length of $ 3 $ , the result will be names “AABAD” and “CBDRD”.

You wonder how many different names Vasya can write instead of name number $ 1 $ , if Vasya is allowed to perform any number of the described actions. As Vasya performs each action, he chooses numbers $ i $ , $ j $ , $ k $ independently from the previous moves and his choice is based entirely on his will. The sought number can be very large, so you should only find it modulo $ 1000000007 $ $ (10^{9}+7) $ .

输入格式

The first input line contains two integers $ n $ and $ m $ ( $ 1<=n,m<=100 $ ) — the number of names and the length of each name, correspondingly. Then $ n $ lines contain names, each name consists of exactly $ m $ uppercase Latin letters.

输出格式

Print the single number — the number of different names that could end up in position number $ 1 $ in the pocket book after the applying the procedures described above. Print the number modulo $ 1000000007 $ $ (10^{9}+7) $ .

样例 #1

样例输入 #1

2 3
AAB
BAA

样例输出 #1

4

样例 #2

样例输入 #2

4 5
ABABA
BCGDG
AAAAA
YABSA

样例输出 #2

216

提示

In the first sample Vasya can get the following names in the position number $ 1 $ : “AAB”, “AAA”, “BAA” and “BAB”.

分析

我们看看样例:

AAB
BAA

在这个数据中,每个字符串的各位不相等的数量分别为:2,1,2(AB,A,BA)。

根据组合数中的乘法原理: N = m 1 ∗ m 2 ∗ . . . ∗ m n N = m 1 ∗ m 2 ∗ . . . ∗ m n N=m1∗m2∗...∗mnN=m_1*m_2*...*m_n N=m1m2...mnN=m1m2...mn​。所以我们只需找出每个字符串中各位不相等的数量,再将其相乘即可。

代码

#include<bits/stdc++.h>

#define int long long//以防万一 

const long long p=1000000007;//题目要求取模 

using namespace std;

int m,n;

string s[100000];//输入的字符串 

int ans=1;//总方案数 

bool bo[100000];//用来判断该字母是否重复 

int k;

signed main()
{
	cin>>n>>m;//输入字符串个数,输入每个字符串位数 
	
	for(int i=1;i<=n;i++)//输入n个字符串 
	{
		cin>>s[i];
	}
	
	for(int i=0;i<m;i++)//枚举每一位 
	{
		memset(bo,0,sizeof(bo));//清空 
		
		k=0;//k表示不同的字符的个数 
		
		for(int j=1;j<=n;j++)//枚举在这一位的每一行行 
		{
			if(bo[s[j][i]-65]==0)//这个字符还没有重复 
			{
				bo[s[j][i]-65]=1;//标记 
				
				k++;//不重复数量+1 
			}
		}

		ans=ans*k;//根据乘法原理求总方案数
		
		ans=ans%p; //取模 
	}
	
	cout<<ans;//输出总方案数 
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

harmis_yz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值