当前位置: 首页 > news >正文

视觉设计网站建设荆门刚刚发布的

视觉设计网站建设,荆门刚刚发布的,衢州网站推广,哪里有免费的网站自己做题目大意:交互题。有一个隐藏的括号序列,只由 "(" 和 ")" 组成,保证至少有一个"(" 和一个 ")"。你需要通过若干次查询猜出这个确定的序列。Easy Version:最多查询 550 次Medium Version&…

题目大意:

交互题。有一个隐藏的括号序列,只由 "(" 和 ")" 组成,保证至少有一个"(" 和一个 ")"。

你需要通过若干次查询猜出这个确定的序列。

Easy Version:最多查询 550 次

Medium Version:最多查询 200 次

Hard Version:最多查询 200 次

Solution:

Easy Version

查询次数限制提示我们一次查询要找到两个元素。

首先我们可以通过二分找到一般情况下第一个 “()” 出现的位置,特例是形如 "))))).....(((((" 的序列。

那么对于一般情况,二分一个mid,查询 [1,mid] 这个连续的子序列,如果查询值不为 0,说明这段序列中存在 “()” 。

于是无论哪种情况,我们都可以找到一个 "(" 和一个 ")" 所在的位置(特例就是 n 和 1 )。

然后我们需要构造一个查询方式,每次查询两个位置,如果这两个位置的不同排列组合情况对应不同的查询值,我们就可以确定地判断这两个位置的元素是什么,官解构造方式如下:

Code:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;#define N 1005int T,n,a[N],pl,pr,ans[N];void solve(int x,int y)
{int num;printf("? 6 %d %d %d %d %d %d\n",x,pr,y,pr,pl,pr);cout.flush();scanf("%d",&num);if(num == 1) ans[x] = ans[y] = 2;if(num == 2) ans[x] = 1,ans[y] = 2;if(num == 3) ans[x] = 2,ans[y] = 1;if(num == 6) ans[x] = ans[y] = 1;return;
}int main()
{scanf("%d",&T);while(T --){memset(ans,0,sizeof ans);scanf("%d",&n);int l,r,mid,x,tmp;l = 2,r = n,tmp = 0;while (l <= r){mid = (l + r) >> 1;printf("? %d ",mid);for (int i = 1;i <= mid;++ i)printf("%d ",i);printf("\n");cout.flush();scanf("%d",&x);if(x) tmp = mid,r = mid - 1;else l = mid + 1;}if(!tmp) pl = n,pr = 1;else pl = tmp - 1,pr = tmp;for (int i = 1;i <= n - 1;i += 2) solve(i,i + 1);if(!ans[n]) solve(n - 1,n);printf("! ");for (int i = 1;i <= n;++ i)if(ans[i] == 1) printf("(");else printf(")");printf("\n");cout.flush();}return 0;
}

Medium Version

官解用的是状压的思想,往二进制方向想,也是十分巧妙。

Hard Version

思考我们一次能否查询更多的位置呢?

先观察到一个小性质:在两个合法括号序列中间随便插一个 ")" 就能把这两个合法序列的贡献分开

例如:

()()()  查询值是 6

()())() 查询值是 3 + 1 = 4

构造这样的查询序列:

"s1))s2)s2))s3)s3)s3))s4)s4)s4)s4)s4))......s12))"

当且仅当si == '(' 的时候,它负责的那一段括号序列才有贡献,并且贡献 = gi * (gi + 1) / 2,其中 gi 是第 i 段的 "si)" pairs 的数目。

那么只需满足:

即可对每一段贡献拆开判断。

这里其实用到的是类似 2^n > 2^(n-1) + ... + 2^1 + 2^0 的思想,这样我们从高位到低位一个个判断,如果 查询值 > gi * (gi + 1) / 2,说明第i段有贡献,si == '(',然后把查询值减掉这段的贡献接着判断下去就可以了。

事实上,根据题目“每次查询的序列长度 k <= 1000” 可以知道,我们一次最多能查询13个位置,但是每次查12个也足够通过 hard version 的限制了,每次13个的原理也是一模一样。

最后要注意的是我们是12个12个的查,最后剩下的未知括号位置少于12的时候,需要特殊处理。(可以直接用easy version的方法把最后几个剩余的位置判断了,简单计算一下这样最多查询次数刚好90多,不到100)

Code:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;#define N 1005int T,n,a[N],pl,pr,res,ans[N],g[20],f[20];void preprocess()
{g[1] = f[1] = res = 1;int now = 1;int sum = 1;for (int i = 2;i <= 12;++ i){while (now * (now + 1) / 2 <= sum) ++ now;g[i] = now;f[i] = now * (now + 1) / 2;sum += f[i];res += g[i];}res = res * 2 + 12;return;
}void print(int tot,int pos)
{for (int i = 1;i <= tot;++ i)printf("%d %d ",pos,pr);printf("%d ",pr);return;
}void solve(int x,int y)
{printf("? %d ",res);for (int i = x;i <= y;++ i){int id = i - x + 1;print(g[id],i);}printf("\n");cout.flush();int num;scanf("%d",&num);for (int i = y;i >= x;-- i){int id = i - x + 1;if(num >= f[id]) num -= f[id],ans[i] = 1;else ans[i] = 2;}return;
}void sol(int x,int y)
{int num;printf("? 6 %d %d %d %d %d %d\n",x,pr,y,pr,pl,pr);cout.flush();scanf("%d",&num);if(num == 1) ans[x] = ans[y] = 2;if(num == 2) ans[x] = 1,ans[y] = 2;if(num == 3) ans[x] = 2,ans[y] = 1;if(num == 6) ans[x] = ans[y] = 1;return;
}int main()
{preprocess();scanf("%d",&T);while (T --){memset(ans,0,sizeof ans);scanf("%d",&n);int l,r,mid,x,tmp;l = 2,r = n,tmp = 0;while (l <= r){mid = (l + r) >> 1;printf("? %d ",mid);for (int i = 1;i <= mid;++ i)printf("%d ",i);printf("\n");cout.flush();scanf("%d",&x);if(x) tmp = mid,r = mid - 1;else l = mid + 1;}if(!tmp) pl = n,pr = 1;else pl = tmp - 1,pr = tmp;int now = 0;for (int i = 1;i + 11 <= n;i += 12)solve(i,i + 11),now = i + 11;if(now < n){for (int i = now + 1;i <= n - 1;i += 2) sol(i,i + 1);if(!ans[n]) sol(n - 1,n);}printf("! ");for (int i = 1;i <= n;++ i)if(ans[i] == 1) printf("(");else printf(")");printf("\n");cout.flush();}return 0;
}

一道非常巧妙的构造序列交互题^^

http://www.zhtcad.com/news/265.html

相关文章:

  • 手机端网站开发书籍58同城如何发广告
  • 广东有疫情吗现在seo关键词优化软件
  • 驻马店网站建设价格东莞seo收费
  • 企业网站建设的目的有哪些百度推广官网
  • 淘客怎么用网站做竞价托管
  • wordpress hook 数据库济南seo关键词优化方案
  • 动态Js文件 做网站标题百度移动开放平台
  • 东莞建材网站建设个人网站如何优化关键词
  • 小型企业网站建设毕业论文系统优化的例子
  • 永久免费云服务器推荐seopc流量排行榜企业
  • 自己在家可以做网站吗南安seo
  • 新沂网站建设百度推广登录手机版
  • 开源门户网站cms今日新闻快讯10条
  • 没有照片怎么做网站百度快照收录
  • 网站制作报价大约墨子学院seo
  • 广州市网站建设公司外贸网站优化公司
  • 凡科网建站入门教程关键词指数
  • 做企业网站一般用什么服务器温州seo品牌优化软件
  • 手机网站模板天眼查企业查询
  • 徐汇做网站关键词查找的方法有以下几种
  • 毕业设计代做的网站好随州今日头条新闻
  • 百度网站托管seo这个行业怎么样
  • 网站建设收费标准服务推广平台都有哪些
  • 网站建设的基本流程包括哪些栾城seo整站排名
  • 做我女朋友恶搞网站太原网络营销公司
  • 创意互动网站天津百度推广代理商
  • wordpress getthememod结构优化
  • 创可贴网站怎么做图片大全搜索引擎推广
  • 行政机关网站建设佛山网站搜索排名
  • 西宁网站建设电话百度广告代运营