题目地址:LA6276 - Key Insight
首先,必要条件是每一个长度为k的循环节中,所有字符出现的个数想等(stl的map的==运算符已经重载好了~)
然后,统计新字符串中每一个字符对应在原来字符串的位置,多举几个例子,发现按vector.size() 排序以后,会出现“正方形”规律。这样就很好计数了,每一“块”贡献size的阶乘。
但是在排序之前,当然是对每一位的vector向量取交集了。
现在纠结的问题就是,取完交集以后,是不是排序以后,还有这样的性质呢?
其实一旦出现了交集为空,ans=0; 只要都不是空,那么一定不会出现参差不齐的情况,因为一个vector里面对应的原始字符都是相同的。 这样原来的正方形,依旧会保持正方形。
具体看代码吧
#include<iostream>
#include<map>
#include<string>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
map<int,int> mp[105];
int k,n;
string a,b;
map<char,int> mp_a,mp_b;
vector<int> v[105][105];
vector<int> final[105];
long long factorial(int n)
{
long long ans=1;
for(int i=1;i<=n;i++)
{
ans=ans*i;
}
return ans;
}
void init()
{
for(int i=0;i<105;i++)
for(int j=0;j<105;j++)
{
v[i][j].clear();
}
for(int i=0;i<105;i++)
final[i].clear();
}
vector<int> Common(vector<int> a,vector<int> b)
{
vector<int> ans;
int cnt[105];
memset(cnt, 0, sizeof(cnt));
for(int i=0;i<a.size();i++)
cnt[a[i]]++;
for(int i=0;i<b.size();i++)
cnt[b[i]]++;
for(int i=0;i<100;i++)
if(cnt[i]>1) ans.push_back(i);
return ans;
}
bool sz_cmp(vector<int> a,vector<int> b)
{
return a.size()<b.size();
}
int main()
{
while(cin>>k)
{
cin>>a>>b;
init();
n=a.length();
bool ok=1;
for(int i=0;i<n/k;i++)
{
mp_a.clear();
mp_b.clear();
for(int j=0;j<k;j++)
{
mp_a[a[i*k+j]]++;
mp_b[b[i*k+j]]++;
}
if(mp_a!=mp_b)
{
ok=0;
break;
}
}
if(!ok)
{
cout<<"0"<<endl;
}
else{
for(int i=0;i<n/k;i++)
{
for(int j=0;j<k;j++)
{
char ch=b[i*k+j];
for(int l=0;l<k;l++)
{
if(ch==a[i*k+l])
v[i][j].push_back(l);
}
}
}
for(int i=0;i<k;i++)
final[i]=v[0][i];
for(int i=0;i<k;i++)
{
for(int j=0;j<n/k;j++)
final[i]=Common(final[i],v[j][i]);
}
sort(final,final+k,sz_cmp);
if(final[0].size()==0)
{
cout<<"0"<<endl;
}
else
{
long long ans=1;
int index=0;
while(index<k)
{
ans=ans*factorial(final[index].size());
index+=final[index].size();
}
cout<<ans<<endl;
}
}
}
}
哎... A,费用六,E 二分图 还不会知识点,五一放个假,看了怪兽大学和一直想看的听见夏雨的声音。