CF1557E Assiut Chess(交互题)

Posted huayucaiji 的博客小屋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1557E Assiut Chess(交互题)相关的知识,希望对你有一定的参考价值。

CF1557E Assiut Chess

前言

这篇题解可能会和普通题解不太一样,会很“生动”,希望大家喜欢~

解题思路

我们的主角是国王(K)和王后(Q),那就把舞台交给他们吧!

旁白:这一天王后发现国王藏私房钱,于是决定抓住他(什么辣鸡剧情啊喂!)。国王和王后移动方式见题目,国王率先进入棋盘,选择了一个位置,现在王后进场了……

Q:哼,反正我的攻击距离远,让让他。我就在 \\((1,1)\\) 好啦。反正不管哪个位置开始,我都能抓住他。

K:别说大话!

Q:等着瞧!我现在不知道你在哪里,但我只要保证你一直在我下方就可以了!我该什么时候下移呢?如果我在 \\(i\\) 行,这个糟老头子在 \\(i+1\\) 行,那么我往下,他可以往上,所以,我一定要确保我和他的距离在 \\(2\\) 行以上才能向下一行。怎么做到这一点呢?真实伤脑筋。

K:嘿嘿!你抓不到我的!你就慢慢想吧!我先走一步喽!

Q:啊!我知道了,只要我从这一行 \\((i,1)\\) 位置出发,每次把这一行巡逻一遍,由于国王没法移动两格,一定一直在我的右边,为了不被我抓住,一定会向下逃走的!一旦他向下,我就向下,你跑不了!

旁白:A few moments later.

K:坏了,再这样下去,我一定会输的,她最多只需要 \\(8*8=64\\) 步就够了。我不能一直往下,我可以先跑到离她相对较远的地方,然后往上到 \\(i+1\\) 行!这样她就乱了阵脚了哈哈哈。只要我往上,她就没办法。

Q:糟了,这该怎么办?我不知道他现在是否在 \\(i+1\\)​ 行,只能再巡逻一次了,但是他一直这样往怎么办,我的步数就要变成了 \\((8+x)*8\\)​ 次了(\\(x\\)​ 表示 K 往上的次数)。不对,\\(x\\) ​好像是有范围的,他最多只能往上 \\(7\\),那么我的巡逻次数最多是 \\(120\\) 次。老娘完全不虚你~

旁白:最后王后抓住了国王,拿回了他的钱。The End!!!

不知道这样的形式怎么样,我也不知道怎么心血来潮就写成这样了。。。。

反正核心思想就是关注国王的竖向移动,一旦往下,我们就往下,一旦往上,我们就重新巡逻这一行,由于国王最多往上 \\(7\\) 次,我们一定抓得住他。至于为什么是 \\(7\\) 次,读者自证不难

代码

//Don\'t act like a loser.
//This code is written by huayucaiji
//You can only use the code for studying or finding mistakes
//Or,you\'ll be punished by Sakyamuni!!!
#include<bits/stdc++.h>
using namespace std;

int read() {
	char ch=getchar();
	int f=1,x=0;
	while(ch<\'0\'||ch>\'9\') {
		if(ch==\'-\')
			f=-1;
		ch=getchar();
	}
	while(ch>=\'0\'&&ch<=\'9\') {
		x=x*10+ch-\'0\';
		ch=getchar();
	}
	return f*x;
}

const int MAXN=131;

int n,pos;

string PLA(int x,int y) {
	if(x==0||y==0) {
		puts("???");
	}
	//please let me know the answer (((
	printf("%d %d\\n",x,y);
	pos=y;
	//fflush(stdout);
	string s;
	cin>>s;
	return s;
}

bool patrol(int x) {
	for(int i=(pos==1? 2:1);i<=8;i++) {
		string s=PLA(x,i);
		if(s=="Done") {
			return 1;
		}
		if(s[0]==\'D\') {
			return 0;
		}
		if(s[0]==\'U\') {
			return patrol(x);
		}
	}
	return 0;
} 
void work() {
	pos=1;
	for(int i=1;i<=8;i++) {
		if(PLA(i,pos)=="Done") {
			return ;
		}
		if(patrol(i)) {
			return ;
		}
	}
}

signed main() {
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	
	int t=read();
	
	while(t--) {
		work(); 
	}  


	//fclose(stdin);
	//fclose(stdout);
	return 0;
}


以上是关于CF1557E Assiut Chess(交互题)的主要内容,如果未能解决你的问题,请参考以下文章

CF559C Gerald and Giant Chess

Solution -「CF 793G」Oleg and Chess

CF 559C - Gerald and Giant Chess (组合计数)

题解 CF559C Gerald and Giant Chess

CF559C Gerald and Giant Chess

CF793G Oleg and chess [线段树优化建边,扫描线,最大流]