Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdio>
- #include <cstring>
- #include <string>
- #include <vector>
- #include <cmath>
- #include <cstdlib>
- #include <algorithm>
- #include <set>
- struct node
- {
- bool known;
- int c;
- int p[3];
- };
- node N[512];
- int found;
- int tree_h;
- int x_to_tree[512];
- int x_from_tree[512];
- int asks;
- void getp(int x, int *p, int *c)
- {
- int z = x_to_tree[x];
- *c = 0;
- if (z != 0)
- p[(*c)++] = x_from_tree[(z-1)/2];
- if (z < (1<<(tree_h)) - 1)
- {
- p[(*c)++] = x_from_tree[z*2+1];
- p[(*c)++] = x_from_tree[z*2+2];
- }
- /*printf("? %d\n", x+1);
- printf("%d\n", *c);
- for (int i=0; i<*c; ++i)
- printf("%d ", p[i]+1);
- printf("\n");*/
- }
- void check(int x)
- {
- if (x < 0 || x >= (1<<(tree_h+1))-1)
- throw "asd";
- }
- void ask(int x)
- {
- check(x);
- node &n = N[x];
- if (n.known)
- throw "qwe";
- if (asks == 16)
- {
- found = x;
- return;
- }
- getp(x, n.p, &n.c);
- /*printf("? %d\n", x+1);
- fflush(stdout);
- scanf("\n%d\n", &n.c);
- for (int i=0; i<n.c; ++i)
- {
- scanf("%d", &(n.p[i]));
- --n.p[i];
- }*/
- n.known = true;
- if (n.c == 2)
- found = x;
- ++asks;
- }
- void answer(int x)
- {
- check(x);
- //printf("! %d\n", x+1);
- //fflush(stdout);
- if (x_to_tree[x] != 0)
- {
- printf("\nERROR %d\n", x+1);
- for (int i=0; i<(1<<(tree_h+1))-1; ++i)
- printf("%d, ", x_from_tree[i]+1);
- exit(0);
- }
- }
- int wave(int from, int to)
- {
- node &n = N[to];
- if (!n.known)
- return -1;
- if (n.c == 1)
- return 1;
- for (int i=0; i<n.c; ++i)
- {
- if (n.p[i] == from)
- continue;
- int r = wave(to, n.p[i]);
- if (r >= 0)
- return r + 1;
- }
- return -1;
- }
- int wherego(int x)
- {
- check(x);
- node &n = N[x];
- if (!n.known)
- ask(x);
- if (found >= 0)
- return found;
- if (n.c == 1)
- return n.p[0];
- if (n.c != 3)
- throw "qwe";
- int k[3];
- int z[3];
- int kc = 0;
- for (int i=0; i<3; ++i)
- {
- k[i] = wave(x, n.p[i]);
- if (k[i] >= 0)
- {
- z[kc] = i;
- ++kc;
- }
- }
- if (kc < 2)
- {
- int j = n.p[0];
- if (k[0] >= 0)
- j = n.p[1];
- if(!N[j].known)
- ask(j);
- if (found >= 0)
- return found;
- int prev = x;
- for (;;)
- {
- int w = -1;
- if (N[j].c == 1)
- break;
- for(int l=0; l<N[j].c; ++l)
- if (N[j].p[l] != prev
- && N[N[j].p[l]].known)
- w = N[j].p[l];
- if (w >= 0)
- {
- prev = j;
- j = w;
- }
- else
- {
- int tmp = prev;
- prev = j;
- j = (N[j].p[0] == tmp ? N[j].p[1] : N[j].p[0]);
- ask(j);
- if (found >= 0)
- return found;
- }
- }
- return wherego(x);
- }
- else
- {
- if (k[z[0]]==k[z[1]])
- return n.p[z[1]+1];
- if (k[z[0]]>k[z[1]])
- return n.p[z[0]];
- return n.p[z[1]];
- }
- }
- int solve()
- {
- //scanf("\n%d",&tree_h);
- for (int i=0; i<512; ++i)
- N[i].known = false;
- int next = 0;
- found = -1;
- asks = 0;
- for(int i=0;i<16;++i)
- {
- next = wherego(next);
- if (found >= 0)
- return found;
- }
- return next;
- }
- void random_test()
- {
- tree_h = 7;//2 + (rand()%6);
- int n = (1<<(tree_h+1))-1;
- for (int i=0; i<n; ++i)
- x_from_tree[i] = i;
- std::random_shuffle(x_from_tree, x_from_tree+n);
- int qwe[512] = { 9, 26, 61, 8, 49, 41, 51, 52, 29, 35, 60, 45, 11, 38, 24, 19, 40, 31, 50, 39, 58, 32, 16, 18, 5, 3, 30, 28,
- 62, 43, 22, 36, 46, 47, 12, 44, 56, 59, 15, 37, 13, 25, 27, 48, 53, 57, 54, 55, 34, 7, 63, 20, 6, 2, 4, 23,
- 10, 42, 1, 33, 21, 14, 17, 0,};
- /*int zz = 0;
- for (int i=0; i<512; ++i)
- if (!qwe[i])
- {
- zz = i + 1;
- break;
- }
- printf("=%d=",zz);
- tree_h = 0;
- for (; 1<<(tree_h+1) != zz; ++tree_h) ;
- for (int i=0; i<512; ++i)
- x_from_tree[i] = qwe[i] - 1;*/
- for (int i=0; i<n; ++i)
- x_to_tree[x_from_tree[i]] = i;
- int r = solve();
- if (asks > 16)
- answer(511);
- //printf("%d\n", r);
- answer(r);
- }
- int main()
- {
- for(;;) random_test();
- int n;
- scanf("%d", &n);
- for (int i=0; i<n; ++i)
- {
- int r = solve();
- answer(r);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement