EOJ Monthly 2019.11 B字母游戏

题目见:https://acm.ecnu.edu.cn/contest/231/problem/B/

卡在第二个点和第十二个点上无数次。

和226打电话,226建议双哈希,然后一发过了。。。。(这是226大佬的力量啊)

#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 1005
const int mod[2]={19260817,19190504},mul[2]={29,11};
int hash[2][maxn],ha[2][maxn][10][10],flag[10];
int q[5][10],top[5],n,m,K,ans,a[10],tail,now[2];
char s[maxn];
using namespace std;
struct in
{
    int q[2];
}b[maxn];
bool cmp(in x,in y)
{
    if (x.q[0]==y.q[0]) return x.q[1]<y.q[1];
    return x.q[0]<y.q[0];
}
void dfs(int x,int last)
{
    int i;
    if (x>tail)
    {
        int j,k,t,tot,now=0,cnt;
        for (i=0;i<last;i++)
        {
            if (top[i]==1) return;
            if (top[i]>1) now+=top[i]-1;
        }
        if (now>K) return;
        //printf("%d \n",now);
        for (i=1;i<=n;i++)
            for (t=0;t<=1;t++) b[i].q[t]=hash[t][i];
        for (i=0;i<last;i++)
            for (k=2;k<=top[i];k++)
                for (j=1;j<=n;j++)
                    for (t=0;t<=1;t++) b[j].q[t]=(b[j].q[t]-ha[t][j][q[i][k]][q[i][k]]+ha[t][j][q[i][k]][q[i][1]]+mod[t])%mod[t];
        cnt=0;tot=1;
        sort(b+1,b+n+1,cmp);
        for (j=2;j<=n;j++)
            if (b[j].q[0]==b[j-1].q[0] && b[j].q[1]==b[j-1].q[1]) tot++;
            else
            {
                cnt+=tot*(tot-1)/2;
                tot=1;
            }
        cnt+=tot*(tot-1)/2;
        //printf("%d %d %d\n",cnt,tot,x);
        if (cnt>ans) ans=cnt;
        return;
    }
    for (i=0;i<last;i++)
    {
        q[i][++top[i]]=a[x];
        dfs(x+1,last);
        top[i]--;
    }
    if (last<4)
    {
        q[last][++top[last]]=a[x];
        dfs(x+1,last+1);
        top[last]--;
    }
    dfs(x+1,last);
    return;
}
int main()
{
    int now[2],i,j,k,t;
    scanf("%d%d%d",&n,&m,&K);
    for (i=1;i<=n;i++)
    {
        scanf("%s",s);
        now[0]=1;now[1]=1;
        for (j=0;j<m;j++)
        for (t=0;t<=1;t++)
        {
            for (k=0;k<8;k++)
                ha[t][i][s[j]-‘a‘][k]=(ha[t][i][s[j]-‘a‘][k]+(‘a‘+k)*now[t]%mod[t])%mod[t];
            hash[t][i]=(hash[t][i]+s[j]*now[t]%mod[t])%mod[t];
            now[t]=now[t]*mul[t]%mod[t];
            flag[s[j]-‘a‘]=1;
        }
    }
    for (i=0;i<8;i++)
        if (flag[i]) a[++tail]=i;
    if (K>=tail-1)
    {
        printf("%d",n*(n-1)/2);
        return 0;
    }
    dfs(1,0);
    printf("%d",ans);
    return 0;
} 

原文地址:https://www.cnblogs.com/lsykk/p/12001736.html

时间: 2024-08-04 15:17:28

EOJ Monthly 2019.11 B字母游戏的相关文章

EOJ Monthly 2019.11 E. 数学题(莫比乌斯反演+杜教筛+拉格朗日插值)

传送门 题意: 统计\(k\)元组个数\((a_1,a_2,\cdots,a_n),1\leq a_i\leq n\)使得\(gcd(a_1,a_2,\cdots,a_k,n)=1\). 定义\(f(n,k)\)为满足要求的\(k\)元组个数,现在要求出\(\sum_{i=1}^n f(i,k),1\leq n\leq 10^9,1\leq k\leq 1000\). 思路: 首先来化简一下式子,题目要求的就是: \[ \begin{aligned} &\sum_{i=1}^n\sum_{j=1

EOJ Monthly 2019.2 (based on February Selection) D.进制转换

题目链接: https://acm.ecnu.edu.cn/contest/140/problem/D/ 题目: 思路: 我们知道一个数在某一个进制k下末尾零的个数x就是这个数整除kx,这题要求刚好末尾有m个0,还需要除去高位为0的情况,因此这题答案就是r / kx-(l-1)/kx-(r/kx+1-(l-1)/kx+1). 代码实现如下: 1 #include <set> 2 #include <map> 3 #include <deque> 4 #include &

EOJ Monthly 2019.3A

A. 钝角三角形 单点时限: 3.0 sec 内存限制: 512 MB QQ 小方以前不会判断钝角三角形,现在他会了,所以他急切的想教会你. 如果三角形的三边长分别为 a, b, c (a≤b≤c),那么当满足 a2+b2<c2 且 a+b>c 的时候,这个三角形就是一个由三边长为 a, b, c 构成的钝角三角形. 单单讲给你听肯定是不够的,为了表现自己,QQ 小方现在要考考你. 现在 QQ 小方会给你一个包含 3n 个整数的集合,分别是 {2,3,4,?3n,3n+1} ,他想让你将这个集

EOJ Monthly 2019.2

题解 A 回收卫星 #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define y1 y11 #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #defin

EOJ Monthly 2019.2 E 中位数 (二分+中位数+dag上dp)

题意: 一张由 n 个点,m 条边构成的有向无环图.每个点有点权 Ai.QQ 小方想知道所有起点为 1 ,终点为 n 的路径中最大的中位数是多少. 一条路径的中位数指的是:一条路径有 n 个点,将这 n 个点的权值从小到大排序后,排在位置 ⌊n2⌋+1 上的权值. 思路(官方题解): 考虑二分答案,我们需要验证路径最大的中位数是否 ≥mid . 我们把所有的点权做 −1/1 变换,即 ≥mid 的点权变为 1 ,否则变为 −1 . 根据题面路径中位数的定义,我们可以发现,如果这条路径的中位数 ≥

EOJ Monthly 2019.2 E. 中位数 (二分+dfs)

题目传送门 题意: 在一个n个点,m条边的有向无环图中,求出所有从1到n 的路径的中位数的最大值 一条路径的中位数指的是:一条路径有 n 个点, 将这 n 个点的权值从小到大排序后,排在位置 ⌊n2⌋+1 上的权值. 思路: 看到权值为1~1e9,可以想到用二分答案,然后我们在验证的时候 可以将小于mid的边权设为-1,大于为1这样遍历一遍序列加起来的值 刚好为0 代码: #include<bits/stdc++.h> using namespace std; typedef long lon

[EOJ Monthly] 2019.9

https://acm.ecnu.edu.cn/contest/196/ 这次是ECNU的校内选拔应该会简单一点? 下午嘉定有彩虹,在村(学)子(校)里面转了一圈,学校真大,没什么人,火烧云真美,台风 要 来 了 打开比赛,看看D:要求概率 不会是签到 看看C:这么大的模拟,不是签到 看看A:要么找规律要么SG,然后很长时间都没有人过,可能是SG,算了不管了 后来队里面有人说D是知乎原题 拿到公式开始交 逆元用费马大定理求 敲敲敲... WA WOC??为什么WA,请教了大佬队友,费马大定理会爆

猜字母游戏

猜字母游戏 猜字母游戏——设计数据结构 猜字母游戏——设计程序结构 猜字母游戏——实现字母生成方法 猜字母游戏——实现字母检测方法 猜字母游戏——实现主方法 1 猜字母游戏——设计数据结构 1.1 问题 有猜字母游戏,其游戏规则为:程序随机产生5个按照一定顺序排列的字符作为猜测的结果,由玩家来猜测此字符串.玩家可以猜测多次,每猜测一次,则由系统提示结果.如果猜测的完全正确,则游戏结束,计算玩家的游戏得分并输出:如果没有猜对,则提示猜测的结果,如猜对了几个字符,以及猜对了几个字符的位置等信息,并提

字母游戏

[问题描写叙述] peter喜欢玩字母游戏,于是他编写了一个有趣的游戏.游戏规则是在一个 (N-1) * N的表格里填写字母.规则:对于每一个输入的N,由 (N-1) * N的字母区域的左上角開始,从字母A開始逆时针填充一个字母区域,乘积若超过26继续由新一组的A.B.C??填充,不要求输出边框. [输入] 多组測试数据(数据量在100组以内). 每组測试数据仅仅有一行为一个整数N(1<=N<=30).表示表格的宽度. [输出] 对于每组输入数据.输出N-1行,为填完的表格(N-1行,每行N个