专栏文章

题解:P10649 [ROI 2017] 四轴飞行器编程 (Day 1)

P10649题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@minhfeqr
此快照首次捕获于
2025/12/02 02:28
3 个月前
此快照最后确认于
2025/12/02 02:28
3 个月前
查看原文
非常简单的交互题。题目允许两倍的询问次数纯属多余。接下来介绍一下怎么只询问至多 n1n-1 次得出答案。
首先,观察到序列开始的第一个字符肯定是 (,不然就不合法了。
那第二个字符是什么呢?我们发现如果第二个是 ( 的话,查询 [1,2][1,2] 就会返回 No,否则就是 Yes
以此类推,第三、第四或第 ii 个呢?此时,若 [1,i1][1,i-1] 本身是一个合法的串,那么直接就知道他是 ( 了,继续处理下一位即可。
否则,我们使用判断第二个字符同样的方法。只是此时查询区间的左端点变成了最右边尚未匹配的 (,查询这个区间是否合法。若合法则为 ),否则就是 (
接下来只需要思考如何维护最右边的未匹配的 ( 了。很明显可以考虑使用栈,每次配对后弹出栈顶,新加了 ( 就推入栈。若栈没有任何元素,则代表此时左边的已经全部配对了。
接下来就能轻松的写出代码了!
CPP
#include <bits/stdc++.h>
#define int long long
using namespace std;
 
char ans[50005];
bool query(int l,int r){
    cout<<"? "<<l<<" "<<r<<endl;
    string s;
    cin>>s;
    return s=="Yes";
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    stack<int> s;
    int n;
    cin>>n;
    for (int i=1;i<=n;i++){
        if (s.size()==0){
            ans[i]='(';
            s.push(i);
        }
        else{
            int st=s.top();
            if (query(st,i)){
                ans[i]=')';
                s.pop();
            }
            else{
                s.push(i);
                ans[i]='(';
            }
        }
    }
    cout<<"! ";
    for (int i=1;i<=n;i++) cout<<ans[i];
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...