seuOJ440 - 对对碰

题目描述

这是一道交互题。如果你此前没有接触过交互题,请参考 OI Wiki - STDIO 交互 的相关介绍,并阅读本题的提示部分。

LCL. 最近沉迷于一款“记忆对对碰”小游戏。这款小游戏包含一个 n×mn\times m 的网格,每个小方格上都放置一个背面朝上的卡片,卡片的正面绘制有若干种不同类型的图案(保证每种类型的图案出现偶数次)。在游戏开始后,玩家可以任意选择网格中背面朝上的卡片,并将其翻转。在任意时刻,如果网格中存在两个正面朝上且图案相同的卡片,这两张卡片将会立即消失;如果网格中存在两个正面朝上且图案不同的卡片,这两张卡片会立即被翻转为背面朝上。在玩家执行若干次翻转操作后,如果网格中的卡片已经全部消失,那么玩家将取得胜利。

LCL. 希望你能够通过严格小于 2nm2nm 次翻转取得游戏的胜利,你能做到吗?

输入格式

第一行两个正整数 n,m(1n,m100)n,m(1\le n,m\le 100),表示网格的大小。保证 n×mn\times m 为偶数。

对于你的每一次翻转操作,交互器会提供一个字符串 ss,表示此次翻转卡片的图案类型。保证 ss 的长度不超过 2020,且仅由大小写英文字母组成。

特别地,如果在完成此次翻转操作后,玩家已经取得胜利,交互器会提供一个字符串 “Accepted.”\texttt{“Accepted.”}(不包含引号)。当交互器提供 “Accepted.”\texttt{“Accepted.”} 后,你的程序应当立即结束。

请注意,交互器并不会提供有关当前卡片是否会消失或被自动翻转的信息,因此你需要在自己的程序中维护这些信息。

输出格式

对于每一次翻转操作,按照 ? x y\texttt{? x y} 的方式输出,表示翻转第 xx 行第 yy 列的卡片。

如果你的输出不在游戏的网格范围内,或者尝试翻转一个已经是正面朝上的卡片,或者翻转一张已经消失的卡片,你将会得到 Wrong Answer。

如果你的操作次数大于等于 2nm2nm,你同样会得到 Wrong Answer。

在输出一次翻转操作后,不要忘记输出换行符并刷新标准输出。请使用:

样例

输入样例 1:

2 3

Cat

Cat

Dog

Pig

Dog

Dog

Pig

Accepted.

输出样例 1:

? 1 1

? 1 2

? 1 3

? 2 1

? 1 3

? 2 2

? 2 1

? 2 3

样例说明 1:

+-----+-----+-----+
| Cat | Cat | Dog |
+-----+-----+-----+
| Pig | Dog | Pig |
+-----+-----+-----+

数据范围与提示

1. 关于交互

你可以参考以下 C++ 的代码实现,用于尝试翻转指定位置的卡片并读取结果。

// 调用这一函数时,请确保:
// 1. (x, y) 位置的卡片没有消失
// 2. (x, y) 位置的卡片为背面朝上
// 并且调用这一函数的次数小于 2nm
std::string try_flip(int x, int y) {
    std::cout << "? " << x << " " << y;
    std::cout << std::endl; // 使用 std::endl 无需 flush
    std::string res;
    std::cin >> res;
    if (res == "Accepted.") {
        exit(0);
    }
    return res;
}

2. 关于评测结果