zoukankan      html  css  js  c++  java
  • Codeforces 750 F:New Year and Finding Roots

    传送门
    首先如果一开始就找到了一个叶子,那么暴力去递归找它的父亲,每次随机一个方向(除了已知的儿子)走深度次,如果走到了一个叶子就不是这个方向
    (设根的深度为 (1))这样子最后到达深度为 (3) 的点需要花费 (11)
    注意到此时只有与该点距离不超过 (2) 的点可能是根,这样的没有询问过的点不超过 (6)
    所以只要询问 (5) 次,一共 (16)
    如果一开始不是叶子,那么尝试 (dfs) 到一个叶子,最后再套用上面的做法
    注意每次随机一个方向的时候要判断之前是否已经有一条长度为深度的链(也可以优先选择询问过的点)

    # include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    int h, pre[233], vis[233], n, flg, rt, leaf, actur[233], tot;
    vector <int> son[233];
    
    inline void Ask(int u) {
    	if (vis[u]) return;
    	int cnt, i, v;
    	vis[u] = 1, printf("? %d
    ", u), fflush(stdout);
    	scanf("%d", &cnt);
    	for (i = 0; i < cnt; ++i) scanf("%d", &v), son[u].push_back(v);
    	if (son[u].size() == 2) {
    		rt = u, flg = 1;
    		return;
    	}
    }
    
    void Dfs(int cur) {
    	if (leaf || flg) return;
    	int i, cnt;
    	Ask(cur), cnt = son[cur].size();
    	if (cnt == 1) {
    		leaf = cur;
    		return;
    	}
    	if (leaf || flg) return;
    	for (i = 0; i < cnt; ++i)
    		if (!vis[son[cur][i]]) {
    			pre[son[cur][i]] = cur, Dfs(son[cur][i]);
    			return;
    		}
    }
    
    inline int Check(int u, int ff, int d) {
    	if (d < 0) return 0;
    	Ask(u);
    	if (flg) return 1;
    	if (son[u].size() == 1) return d ? 0 : actur[u] = 1;
    	int i;
    	for (i = 0; i < 3; ++i)
    		if ((son[u][i] ^ ff) && vis[son[u][i]]) {
    			if (Check(son[u][i], u, d - 1)) return actur[u] = 1;
    			return 0;
    		}
    	for (i = 0; i < 3; ++i)
    		if ((son[u][i] ^ ff) && !vis[son[u][i]]) {
    			if (Check(son[u][i], u, d - 1)) return actur[u] = 1;
    			return 0;
    		}
    }
    
    inline int Getfa(int x, int nh) {
    	Ask(x);
    	if (son[x].size() == 1) return son[x][0];
    	if (flg) return 0;
    	int p1, p2, i;
    	for (i = 0; i < 3; ++i) if (actur[son[x][i]]) break;
    	if (i == 0) p1 = 1, p2 = 2;
    	else if (i == 1) p1 = 0, p2 = 2;
    	else p1 = 0, p2 = 1;
    	p1 = son[x][p1], p2 = son[x][p2];
    	if (vis[p2]) swap(p1, p2);
    	return Check(p1, x, h - nh - 1) ? p2 : p1;
    }
    
    void Dfs2(int u, int d) {
    	if (d > 2 || flg) return;
    	if (tot == 6) {
    		rt = u, flg = 1;
    		return;
    	}
    	Ask(u), ++tot;
    	if (flg) return;
    	int i, cnt = son[u].size();
    	for (i = 0; i < cnt; ++i)
    		if (!actur[son[u][i]]) Dfs2(son[u][i], d + 1);
    }
    
    inline void Solve() {
    	int cur, i, nh;
    	memset(pre, 0, sizeof(pre));
    	memset(vis, 0, sizeof(vis));
    	memset(actur, 0, sizeof(actur));
    	scanf("%d", &h), n = (1 << h) - 1, leaf = flg = 0, nh = h;
    	for (i = 1; i <= n; ++i) son[i].clear();
    	cur = rand() % n + 1, Dfs(cur);
    	if (flg) {
    		printf("! %d
    ", rt), fflush(stdout);
    		return;
    	}
    	cur = leaf, actur[cur] = 1;
    	while (nh > 3) {
    		cur = Getfa(cur, nh), --nh, actur[cur] = 1;
    		if (flg) {
    			printf("! %d
    ", rt), fflush(stdout);
    			return;
    		}
    	}
    	tot = 0, Dfs2(cur, 0);
    	printf("! %d
    ", rt), fflush(stdout);
    }
    
    int main() {
    	srand(time(NULL));
    	int test;
    	scanf("%d", &test);
    	while (test--) Solve();
    	return 0;
    }
    
  • 相关阅读:
    myeclipse下dwr.xml配置文件没有自动提示解决办法
    iOS中判断设备系统版本
    iOS9 对ShareSDK的影响(适配iOS 9必读)
    iOS客户端的微信支付接入
    iOS 时间转换总结
    IOS不用AutoLayout也能实现自动布局的类(4)----MyTableLayout表格布局
    IOS不用AutoLayout也能实现自动布局的类(2)----MyFrameLayout 框架布局
    IOS不用AutoLayout也能实现自动布局的类(3)----MyRelativeLayout 相对布局
    iOS不用AutoLayout也能实现自动布局的类(1)----MyLinearLayout
    iOS~runtime理解
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/10383517.html
Copyright © 2011-2022 走看看