codeforces gym 101164 K Cutting 字符串hash

题意:给你两个字符串a,b,不区分大小写,将b分成三段,重新拼接,问是否能得到A;

思路:暴力枚举两个断点,然后check的时候需要字符串hash,O(1)复杂度N*N;

题目链接:传送门

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<queue>
#include<algorithm>
#include<stack>
#include<cstring>
#include<vector>
#include<list>
#include<set>
#include<map>
using namespace std;
#define LL long long
#define pi (4*atan(1.0))
#define eps 1e-8
#define bug(x)  cout<<"bug"<<x<<endl;
const int N=5e3+10,M=2e6+10,inf=1e9+10;
const LL INF=1e18+10,mod=1e9+7;

string a,b,c;
unsigned int ma[N][N],mc[N][N];
int check(int l1,int r1,int l2,int r2,int l3,int r3)
{
    int s=0,e=r1-l1;
    if(ma[s][e]!=mc[l1][r1])return 0;
    s=e+1,e=s+r2-l2;
    if(ma[s][e]!=mc[l2][r2])return 0;
    s=e+1,e=s+r3-l3;
    if(ma[s][e]!=mc[l3][r3])return 0;
    return 1;
}
void output(int l1,int r1,int l2,int r2,int l3,int r3)
{
    for(int i=l1;i<=r1;i++)
        printf("%c",b[i]);
    printf("\n");
    for(int i=l2;i<=r2;i++)
        printf("%c",b[i]);
    printf("\n");
    for(int i=l3;i<=r3;i++)
        printf("%c",b[i]);
    printf("\n");
}
int main()
{
    cin>>a>>b;
    int n=a.size();c="";
    for(int i=0;i<n;i++)
    if(a[i]>=‘A‘&&a[i]<=‘Z‘)a[i]=a[i]-‘A‘+‘a‘;
    for(int i=0;i<n;i++)
    if(b[i]>=‘A‘&&b[i]<=‘Z‘)c+=b[i]-‘A‘+‘a‘;
    else c+=b[i];
    int tot=0;
    for(int i=0;i<n;i++)
    {
        unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
        unsigned int has= 0;
        for(int j=i;j<n;j++)
        {
            has=has*seed+(a[j]);
            ma[i][j]=(has & 0x7FFFFFFF);
        }
    }
    for(int i=0;i<n;i++)
    {
        unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
        unsigned int has= 0;
        for(int j=i;j<n;j++)
        {
            has=has*seed+(c[j]);
            mc[i][j]=(has & 0x7FFFFFFF);
        }
    }
    for(int i=1;i<=n-2;i++)
    {
        for(int j=i;j<=n-2;j++)
        {
            if(check(0,i-1,i,j,j+1,n-1))
            {
                printf("YES\n");
                output(0,i-1,i,j,j+1,n-1);
                return 0;
            }
            if(check(0,i-1,j+1,n-1,i,j))
            {
                printf("YES\n");
                output(0,i-1,j+1,n-1,i,j);
                return 0;
            }
            if(check(i,j,0,i-1,j+1,n-1))
            {
                printf("YES\n");
                output(i,j,0,i-1,j+1,n-1);
                return 0;;
            }
            if(check(i,j,j+1,n-1,0,i-1))
            {
                printf("YES\n");
                output(i,j,j+1,n-1,0,i-1);
                return 0;;
            }
            if(check(j+1,n-1,0,i-1,i,j))
            {
                printf("YES\n");
                output(j+1,n-1,0,i-1,i,j);
                return 0;
            }
            if(check(j+1,n-1,i,j,0,i-1))
            {
                printf("YES\n");
                output(j+1,n-1,i,j,0,i-1);
                return 0;;
            }
        }
    }
    printf("NO\n");
    return 0;
}
时间: 2024-10-11 22:30:20

codeforces gym 101164 K Cutting 字符串hash的相关文章

Codeforces Gym 100187K K. Perpetuum Mobile 构造

K. Perpetuum Mobile Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/problem/K Description The world famous scientist Innokentiy almost finished the creation of perpetuum mobile. Its main part is the energy generator whic

codeforces gym 100357 K (表达式 模拟)

题目大意 将一个含有+,-,^,()的表达式按照运算顺序转换成树状的形式. 解题分析 用递归的方式来处理表达式,首先直接去掉两边的括号(如果不止一对全部去光),然后找出不在括号内且优先级最低的符号.如果优先级相同,则如果是左结合性(+,-,*,/)则选择最右边的一个,如果是右结合性(^)则选择最最左边的一个. 主要恶心的地方在于输出上.主要是记录一下每个点和符号的位置,在递归和返回时传递一些参数. ps:虽然输出比较恶心,但最终实现出来后还是感到十分地身心愉悦. 参考程序 1 #include

Codeforces 898F 字符串hash

F. Restoring the Expression 题意:给出一个字符串,要把它折分成三部分 a.b.c , 使得 a+b=c .输出任何一种可行情况. tags:字符串 hash 因为 a+b=c ,所以 lena.lenb 至少要有一个等于 lenc 或 lenc-1  .所以枚举 lenc,每次检验一下可不可行. 但每次都暴力检验肯定超时,这里把字符串hash 一下,根据 hash值 快速检验. 记一下模板: const int mod = 1e9+7; ll Hash[N], p[N

Codeforces gym Hello 2015 Div1 E

Codeforces gym 100570 problem E (一种处理动态最长回文子串问题的方法) Problem 给一个长度为N的字符串S,字符集是'a'-'z'.进行Q次操作,操作分三种.一,修改位置X的字符为C:二,查询以P位置为中心的最长回文子串的长度,并输出:三,查询以P与P+1的中间位置为中心的最长回文子串的长度,并输出. More 第二种操作子串长度为奇数,一定存在:第三种操作子串长度为偶数,若不存在,输出 -1. Limits Time Limit(ms): 4000(1s足

【模拟】ECNA 2015 I What&#39;s on the Grille? (Codeforces GYM 100825)

题目链接: http://codeforces.com/gym/100825 题目大意: 栅栏密码.给定N(N<=10),密钥为一个N*N的矩阵,'.'代表空格可以看到,'X'代表被遮挡,还有密文字符串S,长度为N*N 每次将这个矩阵顺时针旋转90°,把矩阵中空格对应的位置按照从上到下从左到右的顺序依次填充上密文字符,求最终这个密文字符能否填满N*N的矩阵,能按顺序输出得到的答案,不能输出"invalid grille" 题目思路: [模拟] 直接模拟即可.旋转的坐标公式很好推.

Codeforces gym Hello 2015 Div1 B and Div2 D

Codeforces gym 100571 problem D Problem 给一个有向图G<V,E>和源点S,边的属性有长度L和颜色C,即E=<L,C>.进行Q次询问,每次给定一个点X,输出S到X的最短路的长度(不存在则输出 -1).但要求S到X的路径中相邻两条边颜色不一样. Limits Time Limit(ms): 1000 Memory Limit(MB): 256 |V|, |E|: [1, 10^5] X, S: [1, |V| ] L: [1, 10^9] |C|

uva 10391 Compound Words (字符串-hash)

Problem E: Compound Words You are to find all the two-word compound words in a dictionary. A two-word compound word is a word in the dictionary that is theconcatenation of exactly two other words in the dictionary. Input Standard input consists of a

线段树 + 字符串Hash - 580E Kefa and Watch

Kefa and Watch Problem's Link Mean: 给你一个长度为n的字符串s,有两种操作: 1 L R C : 把s[l,r]全部变为c; 2 L R d : 询问s[l,r]是否是周期为d的重复串. analyse: n最大为1e5,且m+k最大也为1e5,这就要求操作1和操作2都要采用logn的算法,所以用线段树. 对于更新操作,使用区间更新就可解决. 主要是如何在logn的时间内完成询问操作. 我们采用线段树维护hash值的方法. 结合于类似KMP的性质,我们发现,字

bnu36907 Subpalindromes 字符串hash+线段树

bnu36907 Subpalindromes 字符串hash+线段树 题意:给一个字符串(<=1e5), 进行操作和查询(<=1e5). 1)将指定位置的字符改为c 2)询问l-r的子串,是否是回文串. 解法 :区间维护pl和pr,表示从左到右的hash和从右到左的hash,然后在up和query中合并区间,最后判断pl和pr是否相等即可. #include <cstdio> #include <ctime> #include <cstdlib> #inc