Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

Re:晕,我写的AC自动机,为什么老是TLE啊?

Posted by wskwsk at 2010-09-07 14:15:32 on Problem 1204
In Reply To:晕,我写的AC自动机,为什么老是TLE啊? Posted by:wskwsk at 2010-09-06 20:09:58
#include<iostream>
#include<queue>
#include<cstdio>
using namespace std;
const int row[8] = {-1 , -1 ,0 , 1 , 1 , 1 , 0 , -1};
const int col[8] = {0  , 1 , 1 , 1 , 0 , -1 , -1 , -1};
const int setDir[8]={1 , 2, 4, 8 , 16 , 32 , 64 , 128};
char text[1002][1002];
int isVistedDir[1002][1002];
struct node{
       int num;
       int length;
       int count;
       node* next[26];
       node* fail;
       node()
       {
             num = -1;
             length = -1;
             count = 0;
             fail= NULL;
             for(int i = 0 ; i < 26 ; ++i)
               next[i] = NULL;
       }
};
struct result{
       int direct;
       int x;
       int y;
};


struct result res[1002];
int L , C , W , k=0;

void insert(node* trie , char *word ,int num)
{
 node* tmp = trie;
 for(int i = 0 ;word[i]; ++i)
 {
         int x = word[i]-'A';
         if(tmp->next[x] == NULL)
         {
           tmp->next[x] = new node;
         }
         if(!word[i+1])
         {
              tmp->next[x]->num = num;
              tmp->next[x]->length = i+1;
              tmp->next[x]->count+=1;
         }
         tmp = tmp->next[x];
 }     
}
inline void makeFailBFS(node* trie)
{
       node* root = trie;
       queue<node*> que;
       que.push(root);
       while(!que.empty())
       {
          node* front = que.front();
          que.pop();
          int i = 0;
          for( ; i < 26 ; ++i)
          {
            if(front->next[i] != NULL)
            {
                if(front == root)front->next[i]->fail = root;
                else
                {
                    node *tmp = front;
                    while(tmp->fail != NULL)
                    {
                       if(tmp->fail->next[i] != NULL)                                                                                                           
                      {
                         front->next[i]->fail = tmp->fail->next[i];
                         break;
                      }
                      tmp = tmp->fail;
                    }
                    if(tmp->fail == NULL)
                       front->next[i]->fail = trie;
                }  
                que.push(front->next[i]);            
            }                    
          }
       }
}
void search(node* trie , int r ,int c , int dir)
{
     node* root = trie;
     int rr = row[dir];
     int cc = col[dir];
     while(r>=0&&c>=0&&r<L&&c<C)
     {
       isVistedDir[r][c] =  isVistedDir[r][c] | setDir[dir];
       int x = text[r][c]-'A';
       if(root->next[x] != NULL)
       {
         node* tmp = root->next[x];
        // cout << "&" << r << " " << c << endl;
        // cout << "$" << root->next[x]->num << " " << root->next[x]->count<< endl;
         if(tmp->count > 0)
         {
           tmp->count--;
           res[tmp->num].direct = dir;
           res[tmp->num].x = r-(tmp->length-1)*rr;
           res[tmp->num].y = c-(tmp->length-1)*cc;
         }
         while(tmp->fail != NULL)
         {
           if(tmp->fail->count > 0)
           {
              tmp->fail->count--;
              res[tmp->fail->num].direct = dir;
              res[tmp->fail->num].x = r-(tmp->fail->length-1)*rr;
              res[tmp->fail->num].y = c-(tmp->fail->length-1)*cc;
           }
           tmp = tmp->fail;
         }
         r+=rr;
         c+=cc;
         root = root->next[x];
       }
       else
       {
           root = root->fail;
           if(root == NULL)
           {
            r+=rr;
            c+=cc;
            root=trie;
           }
       }
     }
}
int main()
{
    scanf("%d%d%d",&L,&C,&W);
    for(int i = 0 ; i < L ; ++i)
    {
      scanf("%s" , text[i]);
    }
    char word[1002][200];
    struct node* trie = new node;
    for(int i = 0 ; i < W ; ++i)
    {
      scanf("%s" , word[i]);
      insert(trie , word[i] , i);
    }
    makeFailBFS(trie);
    for(int i = 0 ; i < L; ++i)
    {
      for(int j = 0 ; j < C ; ++j)
      {
              if(trie->next[text[i][j]-'A'] != NULL)
              {
               for(int m = 0 ; m < 8 ; ++m)
               {
                 int is = isVistedDir[i][j] >> m & 1;
                 if(is == 0)
                 {
                     //  cout << i << " " << j << "  " << m << endl;
                       search(trie , i , j ,m);
                 }
               }
              }
      }
    }
     for(int i = 0 ; i < W ; ++i)
    {
      printf("%d %d %c\n" ,res[i].x , res[i].y , (char)res[i].direct+'A');
    }
   
    return 0;
}

求大牛们帮忙,为什么别人的枚举可以过,而我的怎么老是tle啊,求优化,我的程序到底哪里比较费时间啊?我的QQ362392585

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator