题目

背景

这是一道交互题。

一共有 \(n\) 个人做成一圈,他们的编号从 \(1\) 到 \(n\)。

现在每个人的手里面都有一个数字 \(a_i\) ,并且保证每个人与他周围两个人的数字差为 \(1\) ,即 \(\mid a_i-a_{i\pm 1}\mid =1\) ,特别地,编号为 \(1\) 与 \(n\) 的人也满足这个规则。

在这个圈里面,编号为 \(i\) 的人的对面坐着的是编号为 \(i+\frac{n}{2}\) 的人(其中 \(i\le \frac{n}{2}\)),现在要你找到哪个人与他对面坐着的那个人手中的数字一样。

程序输出

在最开始,交互程序会给你一个 \(n(2\mid n, n\le 10^5)\) ,表示这个圈里面的人数,然后你可以输出以下两种格式的操作:

  1. ? x 表示你想询问位置为 \(x\) 的人手中的数字,询问不可执行超过 \(60\) 次;
  2. ! x 表示你的程序的答案,即满足 \(a_x=a_{x+\frac{n}{2}}(x\le \frac{n}{2})\) ,特别地,如果找不到答案,则输出 ! -1

交互程序输入

对于操作 \(1\) ,交互程序会输出一个整数 \(a_x\) 表示 \(x\) 编号的人手中的数字。

对于操作 \(2\) ,如果你的答案是错误的,程序会直接退出,且测试结果为 Wrong Answer ,否则若无其他问题则测试结果为 Accepted

题解

一道十分有思维含量的好题 我太弱了,想了一个小时 。

首先,若 \(n=4k+2\) ,那么 \(\frac{n}{2}=2k+1\) ,即对于位置 \(i\) ,它对面的位置 \(i+\frac{n}{2}=i+2k-1\) ,可以发现他们相差奇数个位置,那么一定有他们的奇偶性不同,即他们一定不同,所以当 \(n=4k+2\) 时一定无解,至于 \(n=4k+1\) 或者 \(n=4k+3\) ,那是不可能的,题目保证 \(2\mid n\) 。

所以,只有当 \(4\mid n\) 时才有解,现在我们考虑如何快速求解。

对于位置 \(i,i\in [1,n]\) ,我们设它对面的位置为 \(i'\) ,再记 \(a_i-a_{i'}=t_i\) ,那么一定有 \(2\mid t_i\) 且 \(t_i-t_{i+1}=\pm 2 或 0\),下面给出后者的解释:

  1. 当 \(a_i=a_{i+1}+1\) ,且 \(a_{i'}=a_{(i+1)'}+1\) 时,\(t_{i+1}=a_i-1-a_{i'}+1=a_i-a_{i'}\) ,即 \(t_i-t_{i+1}=0\) ;
  2. 另外两种情况可以用上面的方法自行思考;

现在我们要求的,就是一个位置 \(i\) 能够满足 \(d_i=0\) 。

而我们已经证明 \(t_i\) 之间的差为 \(\pm 2 或 0\) ,那么,假设我们枚举到一个区间 \([l,r]\) ,如果 \(t_l\) 与 \(t_r\) 异号,则满足 \(t_i=0\) 的 \(i\) 一定属于区间 \([l,r]\) 。

为什么?\(t_l\) 一定是通过不断 \(-2\) 或者 \(+2\) 来达到另外一种符号,而在这个过程中一定会经过 \(t_i=0\) 的那个点。


update on 2020.2.5

\(\text{ZXY}\) 大佬在此处提出一个问题:如果 \(t_l\) 与 \(t_r\) 一开始就同号,并且有解怎么办?

我们需要把上面的结论推广一下:如果存在解,那么 \(t_l\) 与 \(t_r\) 一定是异号的。

但特别地,我们为了保证 \(t_l\) 与 \(t_r\) 一开始异号,只需让 \(l=1,r=\frac{n}{2}+1\) 即可。

这样我们就可以保证在我们的区间之中是一定有解的。

那么万一 \(t_l\) 和 \(t_r\) 一开始就是 \(0\) 怎么办?这不就是答案吗......

但是因为这个原因,代码中有一些细节需要更改,详见代码标注 update 部分。


如果还有一些问题,可见程序。

程序

#include<cstdio>
#include<cstdlib> #define rep(i,__l,__r) for(signed i=__l,i##_end_=__r;i<=i##_end_;++i)
#define fep(i,__l,__r) for(signed i=__l,i##_end_=__r;i>=i##_end_;--i)
#define writc(a,b) fwrit(a),putchar(b)
#define mp(a,b) make_pair(a,b)
#define ft first
#define sd second
#define LL long long
#define ull unsigned long long
#define uint unsigned int
#define pii pair< int,int >
#define Endl putchar('\n')
// #define FILEOI
// #define int long long
// #define int unsigned #ifdef FILEOI
# define MAXBUFFERSIZE 500000
inline char fgetc(){
static char buf[MAXBUFFERSIZE+5],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXBUFFERSIZE,stdin),p1==p2)?EOF:*p1++;
}
# undef MAXBUFFERSIZE
# define cg (c=fgetc())
#else
# define cg (c=getchar())
#endif
template<class T>inline void qread(T& x){
char c;bool f=0;
while(cg<'0'||'9'<c)f|=(c=='-');
for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
if(f)x=-x;
}
inline int qread(){
int x=0;char c;bool f=0;
while(cg<'0'||'9'<c)f|=(c=='-');
for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
return f?-x:x;
}
// template<class T,class... Args>inline void qread(T& x,Args&... args){qread(x),qread(args...);}
template<class T>inline T Max(const T x,const T y){return x>y?x:y;}
template<class T>inline T Min(const T x,const T y){return x<y?x:y;}
template<class T>inline T fab(const T x){return x>0?x:-x;}
inline int gcd(const int a,const int b){return b?gcd(b,a%b):a;}
inline void getInv(int inv[],const int lim,const int MOD){
inv[0]=inv[1]=1;for(int i=2;i<=lim;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
}
template<class T>void fwrit(const T x){
if(x<0)return (void)(putchar('-'),fwrit(-x));
if(x>9)fwrit(x/10);
putchar(x%10^48);
}
inline LL mulMod(const LL a,const LL b,const LL mod){//long long multiplie_mod
return ((a*b-(LL)((long double)a/mod*b+1e-8)*mod)%mod+mod)%mod;
} const int MAXN=1e5;
const int INF=1e9+5; int n,a[MAXN+5]; inline int opposite(const int p){return (p+(n>>1)-1)%n+1;} inline int Ask(const int p){
if(a[p]!=INF)return a[p];
printf("? %d\n",p),fflush(stdout);
return scanf("%d",&a[p]),a[p];
} inline int TEST(const int p){
int x=Ask(p),y=Ask(opposite(p));
if(x==y){
printf("! %d\n",p),fflush(stdout);
exit(0);
}
return x>y?1:-1;
} signed main(){
#ifdef FILEOI
freopen("file.in","r",stdin);
freopen("file.out","w",stdout);
#endif
scanf("%d",&n);
if(n%4)return printf("! -1\n"),fflush(stdout),0;
rep(i,1,n)a[i]=INF;
int l=1,r=(n>>1)+1,mid,tl=TEST(l),tr=-tl,tm;
//update: r, tr 的初值
while(l<=r){
tm=TEST(mid=l+r>>1);
if(tl*tm<0)r=mid-1,tr=tm;
else if(tm*tr<0)l=mid+1,tl=tm;
}
return printf("! -1\n"),fflush(stdout),0;
}

「题解」「CF1019B」The hat的更多相关文章

  1. 「ZJOI2019」&「十二省联考 2019」题解索引

    「ZJOI2019」&「十二省联考 2019」题解索引 「ZJOI2019」 「ZJOI2019」线段树 「ZJOI2019」Minimax 搜索 「十二省联考 2019」 「十二省联考 20 ...

  2. 「题解」「美团 CodeM 资格赛」跳格子

    目录 「题解」「美团 CodeM 资格赛」跳格子 题目描述 考场思路 思路分析及正解代码 「题解」「美团 CodeM 资格赛」跳格子 今天真的考自闭了... \(T1\) 花了 \(2h\) 都没有搞 ...

  3. 「题解」「HNOI2013」切糕

    文章目录 「题解」「HNOI2013」切糕 题目描述 思路分析及代码 题目分析 题解及代码 「题解」「HNOI2013」切糕 题目描述 点这里 思路分析及代码 题目分析 这道题的题目可以说得上是史上最 ...

  4. 「题解」JOIOI 王国

    「题解」JOIOI 王国 题目描述 考场思考 正解 题目描述 点这里 考场思考 因为时间不太够了,直接一上来就着手暴力.但是本人太菜,居然暴力爆 000 ,然后当场自闭- 一气之下,发现对 60pts ...

  5. 【题解】「P6832」[Cnoi2020]子弦

    [题解]「P6832」[Cnoi2020]子弦第一次写月赛题解( 首先第一眼看到这题,怎么感觉要用 \(\texttt{SAM}\) 什么高科技的?结果一仔细读题,简单模拟即可. 我们不难想出,出现最 ...

  6. 「题解报告」 P3167 [CQOI2014]通配符匹配

    「题解报告」 P3167 [CQOI2014]通配符匹配 思路 *和?显然无法直接匹配,但是可以发现「通配符个数不超过 \(10\) 」,那么我们可以考虑分段匹配. 我们首先把原字符串分成多个以一个通 ...

  7. 「bzoj1003」「ZJOI2006」物流运输 最短路+区间dp

    「bzoj1003」「ZJOI2006」物流运输---------------------------------------------------------------------------- ...

  8. 「bzoj1925」「Sdoi2010」地精部落 (计数型dp)

    「bzoj1925」「Sdoi2010」地精部落---------------------------------------------------------------------------- ...

  9. 「BZOJ1924」「SDOI2010」 所驼门王的宝藏 tarjan + dp(DAG 最长路)

    「BZOJ1924」[SDOI2010] 所驼门王的宝藏 tarjan + dp(DAG 最长路) -------------------------------------------------- ...

  10. 「LOJ#10051」「一本通 2.3 例 3」Nikitosh 和异或(Trie

    题目描述 原题来自:CODECHEF September Challenge 2015 REBXOR 1​​≤r​1​​<l​2​​≤r​2​​≤N,x⨁yx\bigoplus yx⨁y 表示 ...

随机推荐

  1. Easyui-Tree和Combotree使用注意事项-sunziren

    版权声明:本文为sunziren原创文章,博客园首发,转载务必注明出处以及作者名称. Easyui-Tree和Combotree所使用的数据结构是类似的,在我的上一篇文章<Easyui-Tree ...

  2. Spark学习之路 (四)Spark的广播变量和累加器[转]

    概述 在spark程序中,当一个传递给Spark操作(例如map和reduce)的函数在远程节点上面运行时,Spark操作实际上操作的是这个函数所用变量的一个独立副本.这些变量会被复制到每台机器上,并 ...

  3. Java(三)String类

    一.String类初始化方法 1.初始化一个空字符串 String str=new String();//这里调用了String的无参构造方法 2.初始化一个有值的字符串 String str1=&q ...

  4. Pascal运行错误表

    (A)DOS错误代码 1:错误的功能代码尝试错误的操作系统调用.2:文件未找到程序试图删除.重命名和打开一个不存在的文件.3:目录未发现目录不存在或是错误,也有可能是访问一个不存在的文件.4:打开太多 ...

  5. .NetCore学习笔记:三、基于AspectCore的AOP事务管理

    AOP(面向切面编程),通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是函数式编程的一种衍生范型.利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑 ...

  6. JavaScript 15 Ajax异步登陆

    /** * Created by KING on 2017/11/28. */ var g_xhr_ui;var g_xhr_login;var g_id; $(document).ready(fun ...

  7. PHP常见数组函数总结

    一.数组的一些关于键名和值的基础操作函数 1.获取数组所有的键或值:array_keys() array_values() $arr_keys = array_keys($array); $arr_v ...

  8. 直观获取redis cluster 主从关系

    需求:还是redis-trib.rb脚本获取的信息不足或者太繁杂,这里给出更加直观的一种方法, 说明:已在4.x版本测试通过,3.x不可用. 原生的输出 (1adfa7f3...) keys slot ...

  9. 2019-08-20 纪中NOIP模拟A组

    T1 [JZOJ6310] Global warming 题目描述 给定整数 n 和 x,以及一个大小为 n 的序列 a. 你可以选择一个区间 [l,r],然后令 a[i]+=d(l<=i< ...

  10. Ubuntu 打不开终端 侧边栏消失的解决办法

    在网上找了很多办法,大多不行,具体原因也不太清楚,应该是Unity某些配置被改了. 我是在ubuntu14.04平台利用apt-get卸载python后,关机重启出现"打不开终端和侧边栏消失 ...