人,只有自己站起来,这个世界才能属于他。|

园龄:粉丝:关注:

题解:[AGC044D] Guess the Password

前言

比较可做的交互题,瓶颈在于编辑距离的转化。

思路分析

首先考虑编辑距离是困难的,考虑弱化条件。

因为本题要求确定一个字符串,因此,可以尝试将编辑距离转化为判定子序列相关的信息。

具体地,考虑,对于两个字符串 S,TST 的子序列当且仅当 f(S,T)=|S|

所以我们可以用编辑距离来判定子序列。

这样,我们不难想到,设 g(S) 表示只含有 S 字符集的目标字符串。

初始我们各用一次询问,可以确定 g(S),|S|=1

对于 |S|>1 的情况,g(S) 可以由 g(A)g(B),满足 AB=AB=S

考虑具体的合并方式,比如这样:

S 表示目前已经合并的字符串,它由 ab 合并而来,lr 表示两个子字符串的合并到的下标,现在需要确定当前位置是 al 还是 br,考虑询问 S+al+sufb(r) 是否是答案串的子序列,如果是说明当前位置填 al,否则填 br。不难发现总的询问次数的上界是 |a|+|b|

然后决策 g 的合并过程,一眼看出来是合并果子,根据经典结论,总代价不会超过 O(nlogn),因为常数很小,所以可以通过。

代码实现

#include<bits/stdc++.h>
using namespace std;
int n;
string s[65];
struct node{
	int len;
	string s;
	bool operator<(const node &a)const{
		return a.len<len;
	}
};
int cnt;
int query(string s){
	int ans;
	cnt++;
	if(cnt>850) assert(0);
	cout<<"? "<<s<<endl;
	cin>>ans;
	return ans;
}
priority_queue<node> q;
string merge(string s1,string s2){
	string s3;
	s3.clear();
	int l=0,r=0;
	for(int i=1;i<=s1.size()+s2.size();i++){
		if(n-query(s3+s1[l]+s2.substr(r))==s3.size()+s2.substr(r).size()+1) s3+=s1[l],l++;
		else s3+=s2[r],r++;
		if(l>=s1.size() || r>=s2.size()) break;
	}
	if(l<s1.size()) s3+=s1.substr(l);
	if(r<s2.size()) s3+=s2.substr(r);
	return s3;
}
string get(char a){
	string s1,s2;
	s1.clear();
	s2.clear();
	for(int i=1;i<=128;i++){
		s1+=a;
	}
	int n=query(s1);
	for(int i=1;i<=128-n;i++){
		s2+=a;
	}
	return s2;
}
int main(){
	for(int i=1;i<=26;i++){
		s[i]=get(i+'A'-1);
		if(s[i].size()) q.push((node){s[i].size(),s[i]});
	}
	for(int i=1;i<=26;i++){
		s[i+26]=get(i+'a'-1);
		if(s[i+26].size()) q.push((node){s[i+26].size(),s[i+26]});
	}
	for(int i=1;i<=10;i++){
		s[i+52]=get(i+'0'-1);
		if(s[i+52].size()) q.push((node){s[i+52].size(),s[i+52]});
	}
	for(int i=1;i<=62;i++){
		n+=s[i].size();
	}
	while(q.size()>1){
		string s1=q.top().s;
		q.pop();
		string s2=q.top().s;
		q.pop();
		string s3=merge(s1,s2);
		q.push((node){s3.size(),s3});
	}
	node s1=q.top();
	cout<<"! "<<s1.s<<endl;
	return 0;
}
//Atcod3rIsGreat

本文作者:Kenma

本文链接:https://www.cnblogs.com/Kenma/p/18703271

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   _Kenma  阅读(4)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起