zoj 3817 2014牡丹江网赛 字符串哈希

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5349

比赛的时候没看这道题,遗憾,不过想到算法不难,但是写代码比较考代码能力,我自己写了两次都不行,还是看了别人代码,写下了这个

学到:

1、hash字符串第一个下表为0的空起来,写起来方便

2、hash匹配的全部情况就是以text串的所有位置为起点做匹配,当text比patern小而且text可以循环时,这么确定

3、dfs的时候,为了加快,可以预估计至少需要匹配多长

int L=min(len,n+1-st);  这样写法 节省了很多时间

4、注意预处理hash  B的次方 以及字符串的hash

//#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <set>
#include <queue>
using namespace std;

#define ls(rt) rt*2
#define rs(rt) rt*2+1
#define ll long long
#define ull unsigned long long
#define rep(i,s,e) for(int i=s;i<e;i++)
#define repe(i,s,e) for(int i=s;i<=e;i++)
#define CL(a,b) memset(a,b,sizeof(a))
#define IN(s) freopen(s,"r",stdin)
#define OUT(s) freopen(s,"w",stdout)
const ll ll_INF = ((ull)(-1))>>1;
const double EPS = 1e-8;
const int INF = 100000000;
const ull B=1e8+7;
const int MAXN = 100000+5;
vector< pair<int,int> > ans;
char str[MAXN];
ull ha[9][MAXN],tt[MAXN],hb[MAXN];
//int leg[10],lenp;
int n,m;

void calhb()
{
    hb[0]=0;
    for(int i=1;i<=m;i++)
        hb[i]=hb[i-1]*B+str[i];
}

void read()
{
    ans.clear();
    scanf("%d%d",&n,&m);
    for(int i=0;i<8;i++)
    {
        scanf("%s", str+1);
        int len=strlen(str+1);
        //leg[i]=len;
        ha[i][0]=0;
        for(int j=1;j<=len;j++)
            ha[i][j]=ha[i][j-1]*B+str[j];
        i++;
        reverse(str+1,str+1+strlen(str+1));
        for(int j=1;j<=len;j++)
            ha[i][j]=ha[i][j-1]*B+str[j];
    }
    scanf("%s",str+1);
    calhb();
}

int dfs(int k, int st, int len)
{
    /////////////
    //printf("## k=%d st=%d len=%d\n",k,st,len);
    //////////////
    if(len == 0)return 1;
    int L=min(len,n+1-st);

    if(ha[k][st+L-1]-ha[k][st-1]*tt[L] == hb[m-len+L]-hb[m-len]*tt[L])
    {
        ans.push_back(make_pair(k,st));
        len-=L;
        int bac= k%2?k-1:k+1;
        if(len == 0)return 1;
        for(int i=0;i<8;i++)
            if(i!=bac && dfs(i,1,len))
                return 1;
        ans.pop_back();
    }
    return 0;
}

int solve()
{
    for(int i=0;i<8;i++)
        for(int j=1;j<=n;j++)
        {
            ans.clear();
            if(dfs(i,j,m))
                return 1;
        }
    return 0;
}

vector<int>op;

void out()
{
    op.clear();
    int cnt=0;
    for(int i=0;i<ans.size();i++)
    {
        //printf("## k==%d st=%d\n",ans[i].first,ans[i].second);
        if(ans[i].first%2 == 0)//正序
        {
            for(int j=ans[i].second; j<=n && cnt<m; j++)
            {
                op.push_back(ans[i].first/2*n+j);
                cnt++;
            }
        }
        else
        {
            for(int j=ans[i].second; j<=n && cnt<m; j++)
            {
                op.push_back(ans[i].first/2*n+n-j+1);
                cnt++;
            }
        }
    }
    printf("%d",op[0]);
    for(int i=1;i<op.size();i++)
        printf(" %d",op[i]);
    putchar('\n');
}

int main()
{
    //IN("zoj3810.txt");
    int ncase;
    scanf("%d",&ncase);
    tt[0]=1;
    for(int i=1;i<MAXN;i++)
        tt[i]=tt[i-1]*B;
    while(ncase--)
    {
        read();
        if(solve())
            out();
        else
            puts("No solution!");
    }
    return 0;
}
时间: 2024-10-17 14:04:17

zoj 3817 2014牡丹江网赛 字符串哈希的相关文章

zoj 3818 2014牡丹江网赛

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5350 昨天写死都是WA,今天按枚举a,b,c的长度以及调用string类的函数substr,1A..... 还是调用系统函数代码能短很多而且代码短意味着出错机会少&思考的逻辑更容易...... 写贴个昨天的WA代码  还是不明白为啥WA..... //#pragma comment(linker, "/STACK:102400000,102400000")

zoj 3809 枚举水题 (2014牡丹江网赛 A题)

题目大意:给出一列取样的几个山的高度点,求山峰有几个? Sample Input 291 3 2 4 6 3 2 3 151 2 3 4 5Sample Output 30 1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <algorithm> 5 # include <cmath> 6 # define LL long long 7 us

zoj 3819(2014牡丹江区域赛 A题 )

题意:给出A班和B班的学生成绩,如果bob(A班的)在B班的话,两个班级的平均分都会涨.求bob成绩可能的最大,最小值. A班成绩平均值(不含BOB)>A班成绩平均值(含BOB) && B班成绩平均值(不含BOB)< B班成绩平均值(含BOB) 化简后得 B班成绩平均值(不含BOB) < X < A班成绩平均值(不含BOB) Sample Input 24 35 5 54 4 36 55 5 4 5 31 3 2 2 1Sample Output 4 42 4 1

ZOJ 3826 Hierarchical Notation(2014 牡丹江 H,字符串模拟)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5380 Hierarchical Notation Time Limit: 2 Seconds      Memory Limit: 131072 KB In Marjar University, students in College of Computer Science will learn EON (Edward Object Notation), which is a

ZOJ 3827 Information Entropy (2014牡丹江区域赛)

题目链接:ZOJ 3827 Information Entropy 根据题目的公式算吧,那个极限是0 AC代码: #include <stdio.h> #include <string.h> #include <math.h> const double e=exp(1.0); double find(char op[]) { if(op[0]=='b') return 2.0; else if(op[0]=='n') return e; else if(op[0]=='

ACM学习历程——ZOJ 3829 Known Notation (2014牡丹江区域赛K题)(策略,栈)

Description Do you know reverse Polish notation (RPN)? It is a known notation in the area of mathematics and computer science. It is also known as postfix notation since every operator in an expression follows all of its operands. Bob is a student in

ZOJ 3811 / 2014 牡丹江赛区网络赛 C. Untrusted Patrol bfs/dfs/并查集

Untrusted Patrol Time Limit: 3 Seconds                                     Memory Limit: 65536 KB Edward is a rich man. He owns a large factory for health drink production. As a matter of course, there is a large warehouse in the factory. To ensure t

ACM学习历程——ZOJ 3822 Domination (2014牡丹江区域赛 D题)(概率,数学递推)

Description Edward is the headmaster of Marjar University. He is enthusiastic about chess and often plays chess with his friends. What's more, he bought a large decorative chessboard with N rows and M columns. Every day after work, Edward will place

2014牡丹江 现场赛 F zoj 3824 Fiber-optic Network

首先赞一下题目, 好题 题意: Marjar University has decided to upgrade the infrastructure of school intranet by using fiber-optic technology. There are N buildings in the school. Each building will be installed with one router. These routers are connected by optic