一个搜索题,和HDOJ的DNA那题类似,不过数据范围大了点。给一些序列,让你求一个最短的序列,使这个序列包含所有子串,这题只多确定了第一个字符。
开始算错了状态数,敲了个和DNA一样的BFS,RE,后来看了好半天才发现少算了一个0,悲剧的状态都开不下了。之后发现有一个条件,说答案不超过20位,就越看越像IDA*了,虽然以前DNA那题的IDA*效率不是很高,但这题那么像也只好敲了。
敲好后果断超时,调整了很多次A*函数也没能A掉,后来加了一个要RP的哈希,1.5s水过。
今天又试着用A*写了一遍,竟然1A了,1.3s,优化了一下1s,实在优化不动了,跪舔跪舔。别人有100+ms的代码,等以后power up了再来挑战
IDA*
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 5 int maze[10][8]; 6 int cap[10]; 7 int n; 8 9 int dep; 10 int ans[22]; 11 12 int ht[10000020]; 13 int val[10000020]; 14 15 inline int p(int pos, int x){ 16 return (pos&(7<<(x*3)))>>(x*3); 17 } 18 19 bool dfs(int d, int pos){ 20 21 int h = 0, th = 0; 22 bool col[15]={false}; 23 for(int i=0;i<n;i++){ 24 int tp=p(pos,i); 25 if(cap[i]-tp>th) th= cap[i]-tp; 26 for(int j=tp;j<cap[i];j++){ 27 if(col[maze[i][j]]) continue; 28 col[maze[i][j]]=true; 29 h++; 30 } 31 } 32 if(th>h) h=th; 33 34 if(h+d>dep) return false; 35 if(h==0) return true; 36 37 for(int i=0;i<n;i++){ 38 int tp=p(pos,i); 39 if(cap[i]==tp) continue; 40 int c = maze[i][tp]; 41 bool flag=true; 42 for(int j=0;j<i;j++){ 43 int ttp=p(pos,j); 44 if(ttp>=cap[j]) continue; 45 if(maze[j][ttp]==c){ 46 flag = false; 47 break; 48 } 49 } 50 if(!flag) continue; 51 int tpos=pos; 52 for(int j=i;j<n;j++){ 53 int ttp=p(pos,j); 54 if(ttp>=cap[j]) continue; 55 if(maze[j][ttp]==c) tpos+=(1<<(j*3)); 56 } 57 int th = tpos%10000007; 58 if(ht[th]==dep&&val[th]<=d) continue; 59 ht[th] = dep; 60 val[th] = d; 61 ans[d] = c; 62 if(dfs(d+1,tpos)) return true; 63 } 64 return false; 65 } 66 67 int main(){ 68 while(~scanf("%d",&n)){ 69 memset(ht, -1, sizeof(ht)); 70 memset(val, -1, sizeof(val)); 71 72 memset(maze, -1, sizeof(maze)); 73 for(int i=0;i<n;i++){ 74 scanf("%d",&cap[i]); 75 for(int j=0;j<cap[i];j++){ 76 scanf("%d",&maze[i][j]); 77 } 78 } 79 int k; 80 scanf("%d", &k); 81 int pos=0; 82 for(int i=0;i<n;i++){ 83 pos += ((maze[i][0]==k)<<(i*3)); 84 } 85 86 dep=0; 87 while(true){ 88 if(dfs(0,pos)) break; 89 dep++; 90 } 91 92 printf("%d", k); 93 for(int i=0;i<dep;i++){ 94 printf(" %d", ans[i]); 95 } 96 puts(""); 97 } 98 }
A*
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<queue> 5 #include<map> 6 using namespace std; 7 8 int n; 9 int k[12]; 10 int c[12][8]; 11 12 inline int p(int pos, int x){ 13 return (pos&(7<<(x*3)))>>(x*3); 14 } 15 16 struct S{ 17 int t, h; 18 unsigned pos; 19 int path[22]; 20 21 S(){} 22 S(int _t, unsigned _pos, int _path[]){ 23 t=_t; 24 pos=_pos; 25 //memcpy(pos, _pos, sizeof(pos)); 26 memcpy(path, _path, sizeof(path)); 27 geth(); 28 } 29 30 S(const S& s){ 31 t=s.t; 32 h=s.h; 33 pos=s.pos; 34 //memcpy(pos, s.pos, sizeof(pos)); 35 memcpy(path, s.path, sizeof(path)); 36 } 37 38 void geth(){ 39 // h=0; 40 // for(int i=0;i<n;i++){ 41 // h=max(h, k[i]-pos[i]); 42 // } 43 44 h=0; 45 int th = 0; 46 bool fuck[15]={false}; 47 for(int i=0;i<n;i++){ 48 if(k[i]-p(pos,i)>th) th= k[i]-p(pos,i); 49 for(int j=p(pos,i);j<k[i];j++){ 50 if(fuck[c[i][j]]) continue; 51 fuck[c[i][j]]=true; 52 h++; 53 } 54 } 55 if(th>h) h=th; 56 } 57 58 friend bool operator< (const S& a, const S& b){ 59 if(a.t+a.h!=b.t+b.h) return a.t+a.h>b.t+b.h; 60 return a.h>b.h; 61 //return a.t+a.h>b.t+b.h; 62 } 63 64 65 void show(){ 66 printf("%d %d\n", t, h); 67 printf("== "); 68 for(int i=0;i<t;i++){ 69 if(i) putchar(' '); 70 printf("%d", path[i]); 71 } puts(""); 72 printf("~~ "); 73 for(int i=0;i<n;i++){ 74 if(i) putchar(' '); 75 printf("%d", p(pos,i)); 76 } puts(""); 77 puts("================"); 78 } 79 }; 80 81 bool vis[10000011]; 82 83 void bfs(int ss){ 84 memset(vis,false,sizeof(vis)); 85 86 priority_queue<S> que; 87 int _path[22], _pos=0; 88 for(int i=0;i<n;i++){ 89 _pos |= ((c[i][0]==ss)<<(i*3)); 90 } 91 _path[0]=ss; 92 que.push(S(1, _pos, _path)); 93 94 while(!que.empty()){ 95 S u(que.top()); 96 que.pop(); 97 98 if(u.h==0){ 99 for(int i=0;i<u.t;i++){ 100 if(i) putchar(' '); 101 printf("%d", u.path[i]); 102 } puts(""); 103 return; 104 } 105 106 107 unsigned ht=u.pos%10000007; 108 if(vis[ht]) continue; 109 vis[ht] = true; 110 111 for(int i=0;i<n;i++){ 112 if(p(u.pos,i)==k[i]) continue; 113 bool flag=false; 114 for(int j=0;j<i;j++){ 115 if(p(u.pos,j)==k[j]) continue; 116 if(c[j][p(u.pos,j)]==c[i][p(u.pos,i)]){ 117 flag = true; 118 break; 119 } 120 } 121 if(flag) continue; 122 S v(u); 123 for(int j=i;j<n;j++){ 124 if(c[j][p(u.pos,j)]==c[i][p(u.pos,i)]){ 125 v.pos+=(1<<(j*3)); 126 } 127 } 128 v.path[v.t]=c[i][p(u.pos,i)]; 129 v.t++; 130 v.geth(); 131 que.push(v); 132 } 133 } 134 } 135 136 int main(){ 137 while(~scanf("%d",&n)){ 138 for(int i=0;i<n;i++){ 139 scanf("%d", &k[i]); 140 for(int j=0;j<k[i];j++){ 141 scanf("%d", &c[i][j]); 142 } 143 } 144 int ss; 145 scanf("%d", &ss); 146 bfs(ss); 147 } 148 }