E.电源箱
每次测试时限: 2 秒
每次测试的内存限制:256 兆字节
输入:标准输入
输出:标准输出
这是一个互动问题。
给你 nnn 个方格,索引从 111 到 nnn 。这些方格看起来完全相同,但是每个方格都有一个隐藏的幂值 aia_iai ,它要么是 111 要么是 222 。
您想确定每个方格的幂值。为此,您将进行以下实验。起初, iii -th 方框被放置在数线( 1≤i≤n1 \le i \le n1≤i≤n )上的坐标 iii 处。
您可以进行以下两种类型的查询:
- 交换 xxx " ( 1≤x≤n−11 \le x \le n - 11≤x≤n−1 ):交换当前位于坐标 xxx 和 x+1x + 1x+1 的方格。请注意,此更改是永久性的,会影响所有后续查询。
- 投掷 xxx " ( 1≤x≤n1 \le x \le n1≤x≤n ):向位于坐标 xxx 的方框投掷小球。如果方框的幂值为 ppp ,则小球向前移动 ppp 个单位,到达坐标 x+px + px+p 。如果在新坐标处有一个方格,小球会使用该方格的幂再次跳跃。这个过程一直持续到小球落在一个没有方框的坐标上。作为回答,您将得到小球在停止前的总跳跃次数。
您的任务是使用不超过 ⌈3n2⌉\left\lceil \frac{3n}{2} \right\rceil⌈23n⌉ 的查询(包括交换和抛掷查询)确定每个方格的幂值。
输入
每个测试包含多个测试用例。第一行包含测试用例的数量 ttt ( 1≤t≤5001 \le t \le 5001≤t≤500 )。测试用例说明如下。
每个测试用例的第一行也是唯一一行包含一个整数 nnn ( 2≤n≤10002 \le n \le 10002≤n≤1000 ) - 盒子的数量。
保证所有测试用例中 nnn 的总和不超过 100010001000 。
互动
每个测试用例的交互开始于读取整数 nnn 。
要进行查询,请按以下格式之一输出一行:
-
"交换 xxx "(不带引号)( 1≤x≤n−11 \le x \le n - 11≤x≤n−1 ):交换当前位于坐标 xxx 和 x+1x + 1x+1 的方框。
-
扔 xxx "(不带引号)( 1≤x≤n1 \le x \le n1≤x≤n ):向位于坐标 xxx 的盒子投掷一个球。评委将给出一个整数,代表小球停止前的跳跃次数。
请注意,查询是**区分大小写的。
确定每个方框的功率值后,按以下格式输出一行:
- "! a1 a2 ... ana_1 \space a_2 \space \ldots \space a_na1 a2 ... an "(不带引号):这里, aia_iai 是最初位于坐标 iii ( 1≤i≤n1 \le i \le n1≤i≤n )的方格的幂值。提交最终答案后,进入下一个测试用例。
请注意,提交上一个查询的最终答案不***计入 ⌈3n2⌉\left\lceil \frac{3n}{2} \right\rceil⌈23n⌉ 个查询的限制中。
如果您的程序在一个测试用例中的查询次数超过 ⌈3n2⌉\left\lceil \frac{3n}{2} \right\rceil⌈23n⌉ ,您的程序必须立即终止,并收到 "错误答案 "的判决。否则,程序可能会收到任何其他判决。
输出查询后,不要忘记输出行尾并刷新输出。否则,您将收到 "超过闲置限制 "的提示。为此,请使用
- fflush(stdout) 或 C++ 中的 cout.flush();
- Java 中使用 System.out.flush();
- Python 中的 sys.stdout.flush();
- Rust 中的 std::io::stdout().flush();
- 请参见其他语言的文档。
交互器是非适应性;在整个交互过程中,方框的幂值保持不变。
黑客*
要黑客攻击,请使用以下格式。
第一行应包含一个整数 ttt ( 1≤t≤5001 \le t \le 5001≤t≤500 ) - 测试用例数。
每个测试用例的第一行包含一个整数 nnn ( 2≤n≤10002 \le n \le 10002≤n≤1000 ) - 盒子的数量。
每个测试用例的第二行包含 nnn 个整数 a1,a2,...,ana_1,a_2,\ldots,a_na1,a2,...,an ( 1≤ai≤21 \le a_i \le 21≤ai≤2 ) - 每个方框的幂值。
所有测试用例中 nnn 的总和不应超过 100010001000 。
注
以下是示例中的交互过程:
解决方案 | 评审 | 解释 |
---|---|---|
有 222 个测试用例。 | ||
4 | 第一个测试用例中有 444 个方框。隐藏功率值为 a=[2,1,2,1]a = [2,1,2,1]a=[2,1,2,1] 。 | |
扔 2 | 2 | 向位于坐标 222 的方框扔一个球。小球经过坐标 2→3→52 \to 3 \to 52→3→5 并停在坐标 555 ,因此响应为 222 。 |
交换 3 | 交换位于坐标 333 和 444 的盒子。现在方框 333 位于坐标 444 处,方框 444 位于坐标 333 处。 | |
向位于坐标 222 的方格投掷一个小球。球经过坐标 2→3→4→62 \to 3 \to 4 \to 62→3→4→6 ,停在坐标 666 处,因此响应为 333 。请注意,由于交换了坐标,响应是不同的。 | ||
向坐标 111 处的方框投掷小球。小球经过坐标 1→3→4→61 \to 3 \to 4 \to 61→3→4→6 并停在坐标 666 处,因此响应为 333 。 | ||
!2 1 2 1 | ||
第二个测试案例中有 222 个方框。隐藏的功率值为 a=[1,2]a = [1, 2]a=[1,2] 。 | ||
向坐标 111 处的方格投掷小球。小球经过坐标 1→2→41 \to 2 \to 41→2→4 ,停在坐标 444 ,因此响应为 222 。 | ||
交换 1 | 交换位于坐标 111 和 222 的盒子。现在方框 111 位于坐标 222 ,方框 222 位于坐标 111 。 | |
抛 1 | 1 | 向位于坐标 111 的方格抛掷小球。球经过坐标 1→31 \to 31→3 并停在坐标 333 处,因此响应为 111 。 |
!1 2 |
示例输入和输出中的空行只是为了提高可读性;您不必在解法中输出这些空行。
请注意,在第一个测试用例中,给出的查询实际上不足以唯一确定幂值;给出查询只是为了说明输入/输出格式。
本人思路
- 首先大家题都看了吧,就是让你在⌈3n2⌉\left \lceil\frac{3n}{2} \right \rceil⌈23n⌉次数下找每个点的值;
- 我们先想一下,想要求点的值,我们先用d[i]d[i]d[i]来保存每个点往后的跳的次数
- 接下来我们就可以考虑两种情况,假设现在点为i,那么就看d[i+1]d[i+1]d[i+1]与d[i+2]d[i+2]d[i+2],d[i+1]!=d[i+2]d[i+1]!=d[i+2]d[i+1]!=d[i+2]就很简单,就可以直接判断求值了,而dp[i+1]==dp[i+2]dp[i+1]==dp[i+2]dp[i+1]==dp[i+2]就需要了,先不管标记一下;
- 接下来就判断标记点,把 i与i+1交换,因为i+1肯定是确认的,那么我们就可以确定i的值了,唯一就是加了个交互式;
(蒻蒻)代码欣赏
cpp
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2005;
int d[N],a[N],n,aa;
bool vis[N];
void solve()
{
for(int i=1;i<n;i++)
{
if(vis[i])
{
cout<<"swap "<<i<<'\n';
cout.flush();
cout<<"throw "<<i+1<<'\n';
cout.flush();
cin>>aa;
if(aa==d[i+2]+1)
a[i]=1;
else
a[i]=2;
}
}
if(vis[n])
{
cout<<"swap "<<n-1<<'\n';
cout.flush();
cout<<"throw "<<n-1<<'\n';
cout.flush();
cin>>aa;
if(aa==2)
a[n]=1;
else
a[n]=2;
}
cout<<"! ";
for(int i=1;i<=n;i++)
{
cout<<a[i]<<" ";
}
cout<<'\n';
cout.flush();
}
signed main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int _,m;
cin>>_;
while(_--)
{
cin>>n;
fill(vis+1,vis+1+n,0);
d[n+1]=0;d[n+2]=0;
for(int i=n;i>=1;i--)
{
if(d[i+1]==d[i+2])
{
vis[i]=1;
d[i]=d[i+1]+1;
}
else
{
cout<<"throw "<<i<<'\n';
cout.flush();
cin>>m;
d[i]=m;
if(d[i]==d[i+1]+1)
a[i]=1;
else
a[i]=2;
}
}
solve();
}
return 0;
}```