poj1945 A*,hash,heap,gcd剪枝

一道搜索好题,但是我写的太弱了,tle,比如跑17530这几个数据有问题。

最终交表0ms。

作文以记之。

希望大家多多指教。

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
struct data {
       int a,b,c,v;
}k,heap[1000000];
int tot,first[1000000],x,num;
struct hash {
       int a,b,next;
}g[1000000];

void up(int i) {
     while (i>1) {
           if (heap[i].v<heap[i/2].v) {
              swap(heap[i],heap[i/2]);
              i/=2;
           }
           else break;
     }
}

void down() {
     swap(heap[1],heap[num]);
     num--;
     int i=1;
     while (i*2<=num) {
           int min=heap[i].v;
           int mini=i;
           if (heap[i*2].v<min) 
           {
                                min=heap[i*2].v;
                                mini=2*i;
           }
           if (heap[i*2+1].v<min && i*2+1<=num) 
           {
                                min=heap[i*2+1].v;
                                mini=2*i+1;
           }
           if (mini!=i) {
                        swap(heap[i],heap[mini]);
                        i=mini;
           }
           else break;
     }
}

int gcd(int a,int b) {
    if (b==0) return a;
    else return gcd(b,a%b);
}

int f(data k) {
    int tmp=k.c;
    int b=k.b;
    while (b<x) {
          tmp++;
          b*=2;
    }
    return tmp;
}

void hashcode(int a,int b) {
     int i = a*b%999983;
     tot++;
     g[tot].a=a;
     g[tot].b=b;
     g[tot].next=first[i];
     first[i]=tot;
} 

bool hashfind(int a,int b) {
     int i = a*b%999983;
     bool tmp=false;
     for (int t=first[i];t!=-1;t=g[t].next)
         if (g[t].a==a && g[t].b==b) {
                        tmp=true;
                        break;
         }
     return tmp;
}

void insert(data p,int k1,int k2) {
     int a=min(k1,k2);
     int b=max(k1,k2);
     data k;
     if (b>2*x) return;
     if (a>0 && b>0 && x%gcd(a,b)!=0) return;
     if (a==0 && b==0) return;
     if (!hashfind(a,b)) hashcode(a,b);
     else return;
     
     k.a=a;
     k.b=b;
     k.c=p.c+1;
     k.v=f(k);
     num++;
     heap[num]=k;
     up(num);
}

int main() {
    scanf("%d",&x);
    
    tot=0;
    k.a=0;
    k.b=1;
    k.c=0;
    k.v=f(k);
    memset(g,0,sizeof(g));
    memset(first,-1,sizeof(first));
    hashcode(0,1);
    heap[1]=k;
    num=1;
    
    while (num!=0) {
          data p=heap[1];
          down();
          int a=p.a;
          int b=p.b;
          if (a==x || b==x) {
                   printf("%d\n",p.c);
                   break;
          }
          insert(p,a*2,b);
          insert(p,a*2,a);
          insert(p,b*2,b);
          insert(p,b*2,a);
          insert(p,0,a);
          insert(p,0,b);
          if (a-b>0) insert(p,a-b,a);
          if (a-b>0) insert(p,a-b,b);
          if (b-a>0) insert(p,b-a,a);
          if (b-a>0) insert(p,b-a,b);
          insert(p,a+b,a);
          insert(p,a+b,b);
    }
    return 0;
}


你可能感兴趣的:(c,insert,UP)