1 条题解

  • 0
    @ 2026-9-28 19:37:51

    题意

    题目传送门

    分析

    看到这么小的数据范围,那肯定用得上搜索了呀。

    那怎么搜才是关键,我们可以枚举每个字母的所属按键,也就是可以用 aia_i 记录每种字母的所属按键。之后如何判断每种名字的按法,那就可以用哈希来做,以 b+1b+1 为一个进制位,那么哈希值 numi=numi×(b+1)+asi,jnum_i = num_i \times (b+1) + a_{s_{i,j}}。后面对 numinum_i 从小到大排序,如果 numi≠numi−1num_i \ne num_{i-1} 且 numi≠numi+1num_i \ne num_{i+1},就说明它是独立的,是唯一确定的。

    那么就更新最大值和 colicol_i,后面就根据 colicol_i 输出就行了。

    注意:输出样例之前有一个一点用都没有的数,得先读取扔掉。

    Code

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll b,l;
    ll d;
    string s[1010];
    ll a[30];
    ll ans,col[30];
    ll num[1010];
    void check(){
    	memset(num,0,sizeof num);
    	for(ll i=1;i<=d;i++){
    		for(auto j:s[i])num[i]=num[i]*(b+1)+a[ll(j-'A')]; 
    	}
    	sort(num+1,num+d+1);
    	ll cnt=0;
    	for(ll i=1;i<=d;i++){
    		if(num[i]!=num[i-1]&&num[i]!=num[i+1])cnt++;
    	}
    	if(cnt>=ans){
    		ans=cnt;
    		for(ll i=0;i<l;i++)col[i]=a[i];
    	}
    }
    void dfs(ll step,ll num){
    	if(step==l){
    		if(num==b)check();
    		return ;
    	}
    	if(num>b)return ;
    	if(num+1<=b){
    		a[step]=num+1;
    		dfs(step+1,num+1);
    	}
    	if(num+(l-step-1)>=b){
    		a[step]=num;
    		dfs(step+1,num);
    	}
    	a[step]=0;
    }
    int main(){
    	ll x;
    	cin>>x;
    	cin>>b>>l>>d;
    	for(ll i=1;i<=d;i++)cin>>s[i];
    	a[0]=1;
    	dfs(1,1);
    	cout<<ans<<endl;
    	for(ll i=0;i<l;i++){
    		cout<<char(i+'A');
    		if(col[i]!=col[i+1])cout<<"\n";
    	}
        return 0;
    }
    
    • 1

    信息

    ID
    5060
    时间
    1000ms
    内存
    125MiB
    难度
    10
    标签
    递交数
    3
    已通过
    1
    上传者