交互题。
首先可以通过 $n-k+1$ 次询问确定 $n-k+1$ 个位置的值。
若 $n - k + 1 \ge k$,则直接询问已知的 $k$ 个找到 $m$ 即可。
否则,考虑最后一次询问会产生一个已知的位置 $x$ 和 $k-1$ 个未知的位置,我们可以拿另外一个已知的位置 $y$ 分别替换这 $k-1$ 个未知的位置,然后根据回答与不替换时的回答是否一致判断这个位置与 $x$ 位置上的数的大小关系,即可找到这些数中有多少个比位置 $x$ 上的数小,从而求出 $m$。
```cpp
const int N = 507;
int n, k, a[N];
inline pi ask(vi o) {
vi O = o;
sort(o.begin(), o.end());
cout << '?';
for (auto c : o) cout << ' ' << c;
cout << endl;
fflush(stdout);
int a, b;
cin >> a >> b;
o = O;
return mp(a, b);
}
int main() {
cin >> n >> k;
if (k == 1) return cout << "! 1" << endl, 0;
vi o, q;
for (int i = 1; i <= k; i++) o.pb(i);
for (int i = k; i <= n; i++) {
pi p = ask(o);
a[p.fi] = p.se;
q.pb(p.fi);
if (i != n)
for (ui j = 0; j < o.size(); j++)
if (o[j] == p.fi) o[j] = i + 1;
}
if (n - k + 1 >= k) {
o.clear();
for (int i = 0; i < k; i++) o.pb(q[i]);
pi p = ask(o);
int ans = 0;
for (int i = 0; i < k; i++)
if (a[o[i]] <= p.se) ++ans;
cout << "! " << ans << endl;
return 0;
}
int x = q.back();
q.pop_back();
int y = q.back();
for (ui i = 1; i < o.size(); i++)
if (o[i] == x) swap(o[0], o[i]);
int ans = 0;
for (ui i = 1; i < o.size(); i++) {
int z = o[i];
o[i] = y;
pi p = ask(o);
if (p.fi == x) ans += a[y] < a[x];
else ans += a[x] < a[y];
o[i] = z;
}
cout << "! " << ans + 1 << endl;
return 0;
}
```