题目传送门


题意简述

\(T\) 组数据。

给定 \(n\) 个盒子,\(n\le 10^3\),每个盒子可能有石头或礼物,已知石头的重量严格大于礼物重量且石头重量都相等,礼物的重量可能不同,礼物数量 \(k\) 严格小于 \(\frac{n}{2}\)。

现在你可以与机器交互,每次向其询问两段交集为空的区间

机器会告诉你那段区间里盒子总重更重或相等。

对于每组数据,你最多询问 \(50\) 次,要找出第一个装有礼物的盒子。


题目思路

首先,我们可以从1号位置下手。

分类讨论:

  • 若 \(1\) 号盒子是礼物,答案就是 \(1\)。
  • 若 \(1\) 号盒子是石头,我们可以倍增的向后找,具体见下。

倍增:

每次询问 \(1 \sim len\) 和 \(len+1 \sim 2\times len\),若前一段重,则礼物在 \(len+1 \sim 2\times {len}\),若是相等,\(1 \sim 2\times {len}\) 都是石头,\({len}\) 每次乘 \(2\) 这些询问是 \(\log_2 n\) 的。

举个例子:

一开始,我们问 \(1\) 和 \(2\) 若相同,因为石头一样重,长度一样长,我们又确定了 \(1\) 是石头,所以 \(2\) 也是石头。接着问 \(1\),\(2\) 和 \(3\),\(4\),若重量不同,所以礼物肯定在 \(3 \sim 4\) 中,因为 \(1\sim 2\) 都是石头。

我们找到一段区间中有礼物了,接着去二分找礼物位置。

设礼物在 \(l \sim r\) 中。

我们二分长度 \({le}\) 每次询问 \(1 \sim {le}\) 和 $ l \sim l+{le}-1$,若前者重,礼物在 $ l \sim l + {le} -1$ 中,否则在 $ l + {le} -1 \sim r$ 中,因为前者我们已经确定都是石头了。

二分询问次数:\(\log_2 n\)。

\(1\) 号是石头消耗总次数:\(2\times \log_2 n\)。

现在最重要的是如何确定:\(1\) 是否是石头。

我们知道现在除去 \(1\) 号是石头消耗总次数外还有大约 \(30\) 次机会,每次我们可以随机一个除 \(1\) 以外的位置,判断两个东西的重量,若 \(1\) 更轻,则我们可以知道 \(1\) 一定是礼物,因为没有比石头更重的东西,判断 \(30\) 次后,若没有比 \(1\) 更重的东西,我们可以认为 \(1\) 是石头。 错误概率约为 \((\frac{1}{2})^{30}\) 因为 \(k \le \frac{n}{2}\)。

注意:

  1. 边界问题,倍增时可能没有完全倍增到 \(n\) 位置。
  2. 输出问题,记得刷新缓冲区。

代码:

#include<bits/stdc++.h>
using namespace std;
int t;
signed main()
{
// ios::sync_with_stdio(0);
// cin.tie(0);
srand(time(0));
cin>>t;
while(t--)
{
int n,k;
cin>>n>>k;
int tmp=__lg(n)*2;
int p=1;
for(int i=1;i<=20;i++)
{
cout<<"? 1 1\n";
fflush(stdout);
cout<<"1\n";
fflush(stdout);
int kk=min(rand()%n+2,n);
cout<<kk<<'\n';
fflush(stdout);
string s;
cin>>s;
if(s == "WASTED")
{
return 0;
}
else
{
if(s == "FIRST")
{ }
if(s == "SECOND")
{
p=0;
break;
}
}
}
if(p>0)
{
int flag=1;
int len=1;
for(len=1;2*len<=n;len*=2)
{
int tmpx=1+len;
cout<<"? "<<len<<' '<<len<<'\n';
fflush(stdout);
for(int i=1;i<=tmpx-1;i++)
{
cout<<i<<' ';
fflush(stdout);
}
cout<<'\n';
fflush(stdout);
for(int i=tmpx;i<=tmpx+len-1;i++)
{
cout<<i<<' ';
fflush(stdout);
}
cout<<'\n';
fflush(stdout);
string s;
cin>>s;
if(s == "FIRST")
{
int l=1,r=len,ans=0;
while(l<=r)
{
int mid=(l+r)/2;
cout<<"? "<<mid<<' '<<mid<<'\n';
fflush(stdout);
for(int i=1;i<=mid;i++)
{
cout<<i<<' ';
fflush(stdout);
}
cout<<'\n';
fflush(stdout);
for(int i=tmpx;i<=tmpx+mid-1;i++)
{
cout<<i<<' ';
fflush(stdout);
}
cout<<'\n';
fflush(stdout);
string s1;
cin>>s1;
if(s1 == "FIRST")
{
r=mid-1;
ans=mid;
}
if(s1 == "EQUAL")
{
l=mid+1;
}
}
cout<<"! "<<tmpx+ans-1<<'\n';
fflush(stdout);
flag=0;
goto it;
}
if(s == "SECOND")
{
return 0;
}
if(s == "EQUAL")
{
continue;
}
if(s == "WASTED")
{
return 0;
}
}
it:;
if(flag)
{
int l=1,r=n-len,ans=0,tmpx=len+1;
while(l<=r)
{
int mid=(l+r)/2;
cout<<"? "<<mid<<' '<<mid<<'\n';
fflush(stdout);
for(int i=1;i<=mid;i++)
{
cout<<i<<' ';
fflush(stdout);
}
cout<<'\n';
fflush(stdout);
for(int i=tmpx;i<=tmpx+mid-1;i++)
{
cout<<i<<' ';
fflush(stdout);
}
cout<<'\n';
fflush(stdout);
string s1;
cin>>s1;
if(s1 == "FIRST")
{
r=mid-1;
ans=mid;
}
if(s1 == "EQUAL")
{
l=mid+1;
}
}
cout<<"! "<<tmpx+ans-1<<'\n';
fflush(stdout);
}
}
else
{
cout<<"! 1\n";
fflush(stdout);
continue;
}
}
return 0;
}

Find a gift的更多相关文章

  1. USACO . Greedy Gift Givers

    Greedy Gift Givers A group of NP (2 ≤ NP ≤ 10) uniquely named friends has decided to exchange gifts ...

  2. CF# Educational Codeforces Round 3 B. The Best Gift

    B. The Best Gift time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  3. 快来玩“Gift大转盘”百分百赚好礼

    现在开始到今年的最后一天,你天天都可以来转100%中奖的“ Gift大转盘 ”.代金券.产品折扣.精美纪念礼,没有多余规则.全部网友都可参加,转到就是你赚到,赶快转起来吧! >>活动主页& ...

  4. Gift Hunting(分组背包)

    Gift Hunting Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...

  5. Codeforces Educational Codeforces Round 3 B. The Best Gift 水题

    B. The Best Gift 题目连接: http://www.codeforces.com/contest/609/problem/B Description Emily's birthday ...

  6. 1002 GTY's birthday gift

    GTY's birthday gift                                                                       Time Limit ...

  7. [light oj 1328] A Gift from the Setter

    1328 - A Gift from the Setter   Problem setting is somewhat of a cruel task of throwing something at ...

  8. 119 - Greedy Gift Givers

     Greedy Gift Givers  The Problem This problem involves determining, for a group of gift-giving frien ...

  9. HDU 5171 GTY's birthday gift 矩阵快速幂

    GTY's birthday gift Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe ...

  10. USACO Section 1.1-2 Greedy Gift Givers

    Greedy Gift Givers 贪婪的送礼者 对于一群(NP个)要互送礼物的朋友,GY要确定每个人送出的钱比收到的多多少. 在这一个问题中,每个人都准备了一些钱来送礼物,而这些钱将会被平均分给那 ...

随机推荐

  1. HashMap如何计算初始化容量,最大容量是多少

    摘要:结合HashMap源码,介绍HashMap如何确定初始化容量,其最大容量是多少.   更多关于HashMap的知识点,请戳<HashMap知识点梳理.常见面试题和源码分析>.   本 ...

  2. JVM划重点:引用类型、垃圾回收算法和内存划分

    一.Java四种引用类型    每种编程语言都有操作内存中元素的方式,例如在 C 和 C++ 里是通过指针,而在 Java 中则是通过"引用"(Reference).在 Java ...

  3. gcc、g++命令

    gcc 与 g++ 分别是 gnu 的 c & c++ 编译器 gcc/g++ 在执行编译工作的时候,总共需要4步: 1.预处理,生成 .i 的文件[预处理器cpp] 2.将预处理后的文件转换 ...

  4. 「Uniapp」一些常用方法的封装

    弹窗 - showModal /** * 封装 uni.showModal * @param {Object|String} options 配置对象或提示内容 * @param {String} [ ...

  5. 【HarmonyOS 5开发入门】DevEco Studio安装配置完全指南

    前言 随着华为鸿蒙OS的快速发展,越来越多的开发者开始关注并投入到这个新兴的生态系统中.作为开发鸿蒙OS应用的第一步,安装并配置好DevEco Studio开发环境至关重要.本文将详细介绍如何下载.安 ...

  6. Java利用ChromeDriver插件网页截图(Wondows版+Linux版)

    chromedriver是谷歌浏览器驱动,用来模拟谷歌运行操作的一个工具,本文主要讲解Java后端利用此插件进行网页截图,并且适配Linux部署. 环境准备 Wondows服务器或电脑 本机需安装Ch ...

  7. dotnet 代码调试方法

    本文将会从基础到高级,从简单到复杂的顺序,告诉大家如何调试 dotnet 系应用,特别是桌面端应用.本文将会向大家介绍使用 VisualStudio 大量的功能用来提高调试效率,穿插着也会介绍一些好用 ...

  8. .NET 8性能优化全攻略:让你的应用飞起来!

    大家好!我是.NET修仙日记的掌门人,今天我们来聊聊.NET 8的性能优化技巧.随着.NET 8的发布,微软带来了更多性能改进的可能性.无论你是开发Web应用.微服务还是桌面程序,这些优化技巧都能让你 ...

  9. define##的作用

    转载 博客园 C++/C 宏定义(define)中# ## 的含义

  10. matlab 求解高阶方程

    简介 van der Pol 方程 code dy = @(t,y)[y(2); 1000 * (1-y(1)^2)*y(2)-y(1)]; % 定义匿名函数 [t,y]= ode15s(dy,[0 ...