time limit per test2 seconds

memory limit per test256 megabytes

inputstandard input

outputstandard output

This is an interactive problem. In the interaction section below you will find the information about flushing the output.

The New Year tree of height h is a perfect binary tree with vertices numbered 1 through 2h - 1 in some order. In this problem we assume that h is at least 2. The drawing below shows one example New Year tree of height 3:

Polar bears love decorating the New Year tree and Limak is no exception. To decorate the tree, he must first find its root, i.e. a vertex with exactly two neighbours (assuming that h ≥ 2). It won’t be easy because Limak is a little bear and he doesn’t even see the whole tree. Can you help him?

There are t testcases. In each testcase, you should first read h from the input. Then you can ask at most 16 questions of format “? x” (without quotes), where x is an integer between 1 and 2h - 1, inclusive. As a reply you will get the list of neighbours of vertex x (more details in the “Interaction” section below). For example, for a tree on the drawing above after asking “? 1” you would get a response with 3 neighbours: 4, 5 and 7. Your goal is to find the index of the root y and print it in the format “! y”. You will be able to read h for a next testcase only after printing the answer in a previous testcase and flushing the output.

Each tree is fixed from the beginning and it doesn’t change during your questions.

Input

The first line of the input contains a single integer t (1 ≤ t ≤ 500) — the number of testcases.

At the beginning of each testcase you should read from the input a single integer h (2 ≤ h ≤ 7) — the height of the tree. You can’t read the value of h in a next testcase until you answer a previous testcase.

Interaction

To ask a question about neighbours of vertex x, print “? x” (without quotes) on a separate line. Note, you must print an end-of-line character after the last character of the line and flush your output to get a response.

The response will consist of two lines. The first line will contain a single integer k (1 ≤ k ≤ 3) — the number of neighbours of vertex x. The second line will contain k distinct integers t1, …, tk (1 ≤ t1 < … < tk ≤ 2h - 1) — indices of neighbours of vertex x, gives in the increasing order.

After asking at most 16 questions you have to say y — the index of the root. Print “! y” (without quotes) and an end-of-line character, and flush the output.

Each tree is fixed from the beginning and it doesn’t change during your questions.

You can get Idleness Limit Exceeded if you don’t print anything or if you forget to flush the output.

To flush you can use (just printing a query/answer and end-of-line):

fflush(stdout) in C++;

System.out.flush() in Java;

stdout.flush() in Python;

flush(output) in Pascal;

See the documentation for other languages.

In any moment if the program reads h = 0 or k = 0 it should immediately terminate normally (for example, calling exit(0)). It means that the system detected incorrect request/output from your program and printed 0 because if can’t process your requests anymore. In this case you’ll receive verdict “Wrong Answer”, but if you ignore case h = 0 or k = 0 it could lead to “Runtime Error”, “Time/Memory limit exceeded” or any other verdict because your program could read a trash from the closed input stream.

Hacking. To hack someone, use the following format:

The first line should contain a single integer t equal to 1 (only one testcase is allowed in hacks). The second line should contain a single integer h. Each of next 2h - 2 lines should contain two distinct integers ai and bi (1 ≤ ai, bi ≤ 2h - 1), denoting two nodes connected with an edge. The printed edges must form a perfect binary tree of height h.

Of course, contestant programs will not be able to see this input.

Examples

input

1

3

3

4 5 7

2

1 2

1

2

output

? 1

? 5

? 6

! 5

input

2

2

1

3

2

1 2

2

1 2

4

3

3 12 13

output

? 1

? 3

? 3

! 3

? 6

! 1

Note

In the first sample, a tree corresponds to the drawing from the statement.

In the second sample, there are two two testcases. A tree in the first testcase has height 2 and thus 3 vertices. A tree in the second testcase has height 4 and thus 15 vertices. You can see both trees on the drawing below.

【题目链接】:http://codeforces.com/contest/750/problem/F

【题解】

/*
首先任意找一个点v;
如果它的邻居数为x
如果x==1(x==3的话就要找两个叶子节点了,x==2的情况归到x==3的情况里面去);
{
则这个点是叶子节点;
则我们以这个点为起点再沿着它的其他邻居走,直到找到另外一个叶子节点为止;
设另外一个叶子节点为u;
则记录一下v到u的路径,找到这段路程的中点,则这个中点肯定是这段路程的
所有节点里面高度最高的(树的叶子节点高度设为1,然后往上递增);
设中间这个节点为y
则y如果只有2个邻居,那么它就是根节点;
如果y有3个邻居,则沿着那第3个节点找(肯定是在往上走了,则我们更靠近根节点了;
然后对那个节点做同样的事情;
即也从那个节点开始一直找啊找,找叶子节点u';
根据我们刚才找到的y的高度->就是路程除2,,再根据从y到u'的路程,我们也能算出来
从叶子节点u到u'这个路程中的高度最高的节点y';
且它的高度高于y节点;
这样就又迫近根节点了;
..一直纪录新的y'节点的高度;
直到它的高度大于等于4(或等于n了);
大于等于4之后,剩下的节点就不用再用上面的方法了;
直接就可以枚举出来了;
当高度为n-1
则答案就是剩下的那个;
当高度为n-2;
则需要试探3次;
当高度为n-3;
则需要试探7次;
最后一个根节点可以用排除法,这样就少试一次了;
画一画、发现不会超过16次.balabala;
如下图,是最坏情况;
黑色表示查询的次数,黑色数字旁的节点是这次查询的节点;
(高度为n-3及以上的时候,只要有限次的搜寻就能确定根节点了)
(bfs最多两层);
}
*/

【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%I64d",&x) typedef pair<int,int> pii;
typedef pair<LL,LL> pll; const int MAXN = 256;
const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0); int h,v,num[256],xl1[MAXN],xl2[MAXN],si0,si1;
vector <int> g[256];
bool bo[256]; void get(int x)
{
bo[x] = true;
printf("? %d\n",x);
fflush(stdout);
rei(num[x]);
rep1(i,1,num[x])
{
int y;
rei(y);
g[x].pb(y);
}
} int nex(int x)
{
int len = g[x].size();
rep1(i,0,len-1)
if (!bo[g[x][i]])
return g[x][i];
return g[x][0];
} int main()
{
//freopen("F:\\rush.txt","r",stdin);
int T;
rei(T);
while (T--)
{
memset(bo,false,sizeof bo);
rep1(i,1,200)
g[i].clear(),num[i] = 0;
int n,dep;
rei(n);
si0 = 0,si1 = 0;
v = 1;
get(v);
if (num[v]==1)
dep = 1;
else
{
int x = v,y =v;
xl1[++si0] = v;
while (true)
{
int yy = nex(x);
xl1[++si0] = yy;
get(yy);
x= yy;
if (num[yy] == 1)
break;
}
while (true)
{
int yy = nex(y);
xl2[++si1] = yy;
get(yy);
y = yy;
if (num[yy] == 1)
break;
}
dep = (si0+si1+1)/2;
if (si0>si1)
v = xl1[dep-si1];
else//si0<si1 si0!=si1
v = xl2[dep-si0];
}
while (dep < n && dep<4)
{
si0 = 0;
int x = v;
while (true)
{
int u = nex(x);
get(u);
xl1[++si0] = u;
x = u;
if (num[u]==1)
break;
}
int tdep = (dep+si0+1)/2;
v = xl1[tdep-dep];
dep = tdep;
}
int q,w,e,r,t,y,u;
if (dep<n)
{
q = nex(v);
get(q);
if (num[q]==2)
v = q;
}
if (dep<n-1)
{
w = nex(q);get(w);if (num[w]==2) v = w;
e = nex(q);get(e);if (num[e]==2) v = e;
}
if (dep<n-2)
{
r = nex(w);get(r);if (num[r]==2) v = r;
t = nex(w);get(t);if (num[t]==2) v = t;
y = nex(e);get(y);if (num[y]==2) v = y;
u = nex(e);if (num[v]!=2) v = u;
}
printf("! %d\n",v);
fflush(stdout);
}
return 0;
}

【codeforces 750F】New Year and Finding Roots的更多相关文章

  1. 【codeforces 415D】Mashmokh and ACM(普通dp)

    [codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...

  2. 【codeforces 604D】Moodular Arithmetic

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  3. 【33.33%】【codeforces 608C】Chain Reaction

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  4. 【codeforces 707E】Garlands

    [题目链接]:http://codeforces.com/contest/707/problem/E [题意] 给你一个n*m的方阵; 里面有k个联通块; 这k个联通块,每个连通块里面都是灯; 给你q ...

  5. 【codeforces 707C】Pythagorean Triples

    [题目链接]:http://codeforces.com/contest/707/problem/C [题意] 给你一个数字n; 问你这个数字是不是某个三角形的一条边; 如果是让你输出另外两条边的大小 ...

  6. 【codeforces 709D】Recover the String

    [题目链接]:http://codeforces.com/problemset/problem/709/D [题意] 给你一个序列; 给出01子列和10子列和00子列以及11子列的个数; 然后让你输出 ...

  7. 【codeforces 709B】Checkpoints

    [题目链接]:http://codeforces.com/contest/709/problem/B [题意] 让你从起点开始走过n-1个点(至少n-1个) 问你最少走多远; [题解] 肯定不多走啊; ...

  8. 【codeforces 709C】Letters Cyclic Shift

    [题目链接]:http://codeforces.com/contest/709/problem/C [题意] 让你改变一个字符串的子集(连续的一段); ->这一段的每个字符的字母都变成之前的一 ...

  9. 【Codeforces 429D】 Tricky Function

    [题目链接] http://codeforces.com/problemset/problem/429/D [算法] 令Si = A1 + A2 + ... + Ai(A的前缀和) 则g(i,j) = ...

随机推荐

  1. [1,2,3].forEach(alert);这样的写法有什么利和弊吗?

    以下这个问题遇到了之后.问了太阳神,以下是太阳神的解答: [1,2,3].forEach(alert);这样的写法有什么利和弊吗? 首先forEach使用方法非常easy降低代码量, 可是也有非常多地 ...

  2. Opera mini for S60 custom server

    Opera mini for S60 custom server 在线改服 http://yourshell.info/mo/mini/ 本人贫穷一族,一直在用S60V2,这种手机启动JAVA很占内存 ...

  3. CSDN博客的文章分类和战略规划

    CSDN原创文章已经有300多篇了,现在已经整理了好多个分类目录了. 今天,特别向大家介绍下,每个分类的含义和规划. CSDN博客是我的一个重要的自媒体,也是我的一个战略实践. 我会精心维护这个博客, ...

  4. Oracle学习总结(9)—— Oracle 常用的基本操作

    创建用户,相当于在sqlServer中创建一个数据库  create user 用户名 identified by 密码  修改用户密码  alter user 用户名 identified by 新 ...

  5. AlertDialog的onCreateDialog与onPrepareDialog用法

    场景:在一个Activity中多次使用弹出对话框.而且对话框携带着动态变化的信息数据,这时假设仅仅使用onCreateDialog(int id, Bundle bundle)回调,则会发现第一次以后 ...

  6. 关于jsonp跨域的问题以及解决方法(跨域、同源与非同源)

    什么是跨域? 想要了解跨域,首先需要了解下浏览器的同源机制: JSONP和AJAX相同,都是客户端向服务器端发送请求:给服务器端传递数据 或者 从服务器端获取数据 的方式 JSONP属于非同源策略(跨 ...

  7. JNI之——Can't load IA 32-bit .dll on a AMD 64-bit platform错误的解决

    转载自:http://blog.csdn.net/l1028386804/article/details/46605003 在JNI开发中,Java程序需要调用操作系统动态链接库时,报错信息:Can' ...

  8. 一起talk C栗子吧(第八回:C语言实例--素数)

    各位看官们,大家好,从今天開始.我们讲大型章回体科技小说 :C栗子,也就是C语言实例. 闲话休提, 言归正转. 让我们一起talk C栗子吧! 看官们.上一回中咱们说的是进制转换的样例,这一回咱们说的 ...

  9. 支付宝支付返回通知时 notify_url和return_url的选择

    页面跳转同步通知页面特性(return_url特性) 买家在支付成功后会看到一个支付宝交易提示成功的页面,该页面会停留几秒,然后会自动跳转回商户指定的同步通知页面(参数return_url) 该页面中 ...

  10. nginx服务器,访问时如何不直接显示index.php,而是显示目录

    版权声明:m_nanle_xiaobudiu https://blog.csdn.net/m_nanle_xiaobudiu/article/details/79502787 效果: 这里,我使用的是 ...