刷题记录2015.11.18

原创 2015年11月20日 16:52:20

补上

HDU3065:多组数据有点坑爹

HDU2222:模板,但是换了一种写法,虽然之前那种写法貌似复杂度也是O(N)的(不知道怎么证明,但是感觉和KMP差不多).这种写法构建了一个trie图,复杂度是很显然的O(N)而且代码还短一点,大概要快十分之一。


代码如下:

HDU3065:

#include "cstdio"
#include "cstdlib"
#include "iostream"
#include "algorithm"
#include "cstring"
#include "queue"

using namespace std;

#define MAX_SIZE 2000005
#define INF 0x3F3F3F3F
#define Eps
#define Mod

inline int Get_Int()
{
    int Num = 0, Flag = 1;
    char ch;
    do
    {
        ch = getchar();
        if(ch == '-')
            Flag *= -1;
    }
    while(ch < '0' || ch > '9');
    do
    {
        Num = Num * 10 + ch - '0';
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9');
    return Num * Flag;
}

class Node
{
public:
    Node *Fail, *Next[26];
    int Count;
}*Root, *Empty;

int N, Length;
int Num[1005];

char Str[MAX_SIZE], Virus[1005][55];

inline Node* New()
{
    Node *x = (Node*)(malloc(sizeof(Node)));
    memset(x, 0, sizeof(Node));
    return x;
}

inline void Build_Trie()
{
    Root = New();
    for(int i = 1; i <= N; ++i)
    {
        scanf("%s", Virus[i]);
        Node *temp = Root;
        for(int j = 0, Length = strlen(Virus[i]), To; j < Length; ++j, temp = temp -> Next[To])
        {
            To = Virus[i][j] - 'A';
            if(!temp -> Next[To])
                temp -> Next[To] = New();
        }
        temp -> Count = i;
    }
}

inline void Build_ACAM()
{
    queue<Node*> Queue;
    Queue.push(Root);
    Empty = New();
    for(int i = 0; i < 26; ++i)
        Empty -> Next[i] = Root;
    Root -> Fail = Empty;
    while(!Queue.empty())
    {
        Node *Now = Queue.front(), *temp;
        Queue.pop();
        for(int i = 0 ; i < 26; ++i)
            if(Now -> Next[i])
            {
                for(temp = Now -> Fail; !temp -> Next[i]; temp = temp -> Fail);
                Now -> Next[i] -> Fail = temp -> Next[i];
                Queue.push(Now -> Next[i]);
            }
    }
}

inline void Solve()
{
    Node* Now = Root;
    for(int i = 0; i < Length; ++i)
    {
        if(Str[i] < 'A' || Str[i] > 'Z')
        {
            Now = Root;
            continue;
        }
        int To = Str[i] - 'A';
        while(!Now -> Next[To])
            Now = Now -> Fail;
        Now = Now -> Next[To];
        for(Node *temp = Now; temp != Root; temp = temp -> Fail)
            ++Num[temp -> Count];
    }
    for(int i = 1; i <= N; ++i)
        if(Num[i])
            printf("%s: %d\n", Virus[i], Num[i]);
}

inline void Release(Node *Now)
{
    for(int i = 0; i < 26; ++i)
        if(Now -> Next[i])
            Release(Now -> Next[i]);
    free(Now);
}

int main()
{
    while(cin >> N)
    {
        Build_Trie();
        Build_ACAM();
        scanf("%s", Str);
        Length = strlen(Str);
        Solve();
        Release(Root);
        free(Empty);
        memset(Num, 0, sizeof(Num));
    }
    return 0;
}

HDU2222:

#include "cstdio"
#include "cstdlib"
#include "iostream"
#include "algorithm"
#include "cstring"
#include "queue"

using namespace std;

#define MAX_SIZE 10005
#define INF 0x3F3F3F3F
#define Eps
#define Mod

inline int Get_Int()
{
	int Num = 0, Flag = 1;
	char ch;
	do
	{
		ch = getchar();
		if(ch == '-')
			Flag *= -1;
	}
	while(ch < '0' || ch > '9');
	do
	{
		Num = Num * 10 + ch - '0';
		ch = getchar();
	}
	while(ch >= '0' && ch <= '9');
	return Num * Flag;
}

class Node
{
public:
	Node *Next[26], *Fail;
	int Count;
}*Root, *Empty;

int Length[MAX_SIZE];
int M, N, T, Ans;

char Words[MAX_SIZE][55], Str[1000005];

inline Node* New()
{
	Node *x = (Node*)(malloc(sizeof(Node)));
	memset(x, 0, sizeof(Node));
	return x;
}

inline void Build_Trie()
{
	Root = New();
	for(int i = 1; i <= N; ++i)
	{
		Node *temp = Root;
		for(int j = 0, To; j < Length[i]; ++j, temp = temp -> Next[To])
		{
			To = Words[i][j];
			if(!temp -> Next[To])
				temp -> Next[To] = New();
		}
		temp -> Count++;
	}
}

inline void Build_ACAM()
{
	queue<Node*> Queue;
	Queue.push(Root);
	Empty = New();
	for(int i = 0; i < 26; ++i)
		Empty -> Next[i] = Root;
	Root -> Fail = Empty;
	while(!Queue.empty())
	{
		Node *Now = Queue.front();
		Queue.pop();
		for(int i = 0; i < 26; ++i)
			if(Now -> Next[i])
			{
				Now -> Next[i] -> Fail = Now -> Fail -> Next[i];
				Queue.push(Now -> Next[i]);
			}
			else
				Now -> Next[i] = Now -> Fail -> Next[i];
	}
}

inline void Solve()
{
	Node *Now = Root;
	Ans = 0;
	for(int i = 0; i < M; ++i)
	{
		int To = Str[i];
		Now = Now -> Next[To];
		for(Node* temp = Now; temp != Root; temp = temp -> Fail)
		{
			Ans += temp -> Count;
			temp -> Count = 0;
		}
	}
}

int main()
{
	cin >> T;
	while(T--)
	{
		N = Get_Int();
		for(int i = 1; i <= N; ++i)
		{
			scanf("%s", Words[i]);
			Length[i] = strlen(Words[i]);
			for(int j = 0; j < Length[i]; ++j)
				Words[i][j] -= 'a';
		}
		Build_Trie();
		Build_ACAM();
		scanf("%s", Str);
		M = strlen(Str);
		for(int i = 0; i < M; ++i)
			Str[i] -= 'a';
		Solve();
		printf("%d\n", Ans);
	}
	return 0;
}


版权声明:都是TATQAQ2333大爷教我的

bzoj刷题(shui)记录

放假刷了一个月的水题,集中写一下题解吧。bzoj1858:线段树随便维护一下。 code bzoj2705:莫比乌斯反演裸题。 code bzoj1202:并查集,但是我写了一种跟floyd很像的...
  • FZHvampire
  • FZHvampire
  • 2015年08月31日 11:26
  • 1655

Python 刷题(想练python的可以对着刷一刷,持续更新)

这道题的意思是说
  • geniusluzh
  • geniusluzh
  • 2014年04月23日 10:36
  • 7734

leetcode刷题经验

语言不是最重要的,思想最重要从做上面的题,我发现我更擅长一些数学技巧不高的程序题,习惯靠直觉立马书写代码,而非严格推理之后,再书写代码对于链表的题比较擅长,链表可以在纸上画画,关键要考虑的问题,就是链...
  • basycia
  • basycia
  • 2016年02月28日 15:31
  • 1406

谈谈程序员面试之刷题

前一段时间有一个非常有趣的故事(http://www.pingwest.com/sorry-cant-hire-you/  ),Max Howell (Homebrew的作者) 在 Google 面试...
  • github_39335046
  • github_39335046
  • 2017年06月29日 17:03
  • 1743

LeetCode刷题指南(一)

以下是我个人做题过程中的一些体会: 1. LeetCode的题库越来越大,截止到目前,已经有321个问题了。对于大多数人来说,没有时间也没有必要把所有题目都做一遍(时间充裕可以随意)。刷个100题左...
  • Lnho2015
  • Lnho2015
  • 2016年03月23日 15:02
  • 38335

比较好的刷题网站推荐

http://www.cnblogs.com/DarrenChan/p/5648422.html 1.Leetcode鼎鼎大名的Leetcode,据不完全统计在上面被刷过的题可以围绕地球...
  • dipolar
  • dipolar
  • 2017年03月09日 11:56
  • 753

手把手教你用C++ 写ACM自动刷题神器(冲入HDU首页)

少年,作为苦练ACM,通宵刷题的你 是不是想着有一天能够荣登各大OJ榜首,俯瞰芸芸众生,唔....要做到这件事情可是需要一定天赋的哦! 博主本身也搞过一段时间的acm,对刷题深有感触,不信可以去看我...
  • qq_28954601
  • qq_28954601
  • 2016年04月24日 10:12
  • 2128

topcoder 刷题笔录 初级篇(一)

摘要:本系列文章为在topcoder上的刷题记录和心得,计划刷题500道。其中,初级题目30道,撰文三篇;中级题目60道,撰文六篇;其他高级题目100道,撰文10篇。 1.题目1——SRM146 ...
  • trochiluses
  • trochiluses
  • 2013年12月20日 16:00
  • 2555

一、简单刷题APP(题库是Excel)之项目功能和效果图

这是本人的第一篇博客,自己也是菜鸟,如有不妥之处,欢迎指教,谢谢了。只是想借此机会自己也整理一下笔记。 在此想感谢各位牛人还有这个平台,我在学习和做项目的过程中遇到了很多问题,CSDN博客大都能解决...
  • qq_35638837
  • qq_35638837
  • 2017年04月03日 14:16
  • 700

操作系统刷题(一)

1.  UNIX操作系统是一种多用户分时操作系统,可用于PC机。 2.分时操作系统:是一种联机的多用户交互式的操作系统。一般采用时间片轮转的方式使一台计算机为多个终端服务。对每个用户能保证足够快的响...
  • alwaystry
  • alwaystry
  • 2017年06月03日 22:47
  • 398
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:刷题记录2015.11.18
举报原因:
原因补充:

(最多只允许输入30个字)