求助分治
查看原帖
求助分治
351239
zunfxsinw楼主2022/8/8 15:33

思路是设f(i,j,cur)为在区间[l,r]内,cur是否能胜出,则cur的对手一定一个来自cur所在的一半区间,另一个来自另一个区间,选择cur能打过的a最大的对手晋级,继续递归。能过讨论区的卡贪心数据。哪儿有问题呢?

记录

#include <bits/stdc++.h>
using namespace std;
int m,k,a[(1<<18)+5];
bool dfs(int l,int r,int cur)
{
	int p = (l+r)/2;
	/*if(l+1 == r)
	{
		if(cur == l && a[cur]+m >= a[r]) return true;
		if(cur == r && a[cur]+m >= a[l]) return true;
		return false;
	}*/
	if(l == r) return true;
	if(cur <= p)
	{
		int maxn[2],ok = 0;
        \\maxn[0]是最大值大小,maxn[1]是下标
		maxn[0] = maxn[1] = 0;
		for(int i = p+1;i <= r;i++)
		{
			if(i == cur) continue;
			if(a[cur]+m >= a[i] && a[i] >= maxn[0]) maxn[0] = a[i],maxn[1] = i,ok = 1;
		}
		if(!ok) return false;
		if(dfs(l,p,cur) && dfs(p+1,r,maxn[1])) return true;
		else return false;
	}
	else
	{
		int maxn[2],ok = 0;
		maxn[0] = maxn[1] = 0;
		for(int i = l;i <= p;i++)
		{
			if(i == cur) continue;
			if(a[cur]+m >= a[i] && a[i] >= maxn[0]) {maxn[0] = a[i],maxn[1] = i,ok = 1;}
		}
		if(!ok) return false;
		if(dfs(p+1,r,cur) && dfs(l,p,maxn[1])) return true;
		else return false;
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	int t; cin >> t;
	while(t--)
	{
		cin >> k >> m;
		for(int i = 1;i <= (1<<k);i++) cin >> a[i];
		if(k == 0) {cout << "Kotori\n"; continue;}
		if(dfs(1,(1<<k),1)) cout << "Kotori\n";
		else cout << "Yoshino\n";
		//cout << dfs(5,8,8);
	}
    return 0;
}
2022/8/8 15:33
加载中...