E. Arranging The Sheep
传送门
题目大意:给定n个点的位置(一维),求最小移动步数(每次只能移一步,且不能越过其他点),使它们挨在一起
思路:求中位数
不妨将点都转化到数轴上,求一个点,使得所有点到它的距离之和最小,初中就学过这个点是它们的中位数。
设每个点到处于中位数那点的距离为xi,每个点与中位数的下标差为yi,则答案为∑(xi -yi)(i:1~n)
F1. Guess the K-th Zero (Easy version)
传送门
题目大意:有一个长度为n的隐藏01串,求第k个0的位置,每次可以询问得到区间中1的数量
我的交互题一血
二分询问的右界
假设每次回答为a,则当 a + k <= mid 时,说明整个区间大了,r=mid-1
反之 l = mid + 1(endl好像会自动清楚缓存区?不需要fflush(stdout)了)
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <vector>
#include <queue>
using namespace std;
#define _for(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define _rep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(v,s) memset(v,s,sizeof(v))
#define pb push_back
#define IOS ios::sync_with_stdio(false)
#define int long long
typedef long long ll;
const int N=2e5+10;
int n,t,k;
void solve()
{
int l=1,r=n;
int res=n;
//二分询问的右界
while( l<=r )
{
int mid=(l+r)>>1;
cout<<"? "<<1<<" "<<mid<<endl;
int a;
cin>>a;
// a + k <= mid右界 ,说明区间大了
if( mid - a >= k) r=mid-1;
else l = mid+1;
}
cout<<"! "<<l<<endl;
}
signed main()
{
///!!!
// freopen("data.txt","r",stdin);
//!!!
IOS;
cin>>n>>t>>k;
solve();
}