• Codeforces Round #Pi (Div. 2) —— D One-Dimensional Battle Ships


    题目的意思是:

    如今有一个长度为n,宽为1的方格,在上面能够放大小为1*a船,然后输入为n,k,a。分别为平地的大小,船的数量,船的长度。

    一个叫alice的人已经在地图上摆好了船的位置。

    然后bob总共能够有m次攻击的机会,然后他每次攻击的点为xi。可是alice并不会告诉它有没有打中(也就是说每次都觉得他是miss的)。问你,bob能够在第几次攻击的时候猜測出alice在撒谎,假设猜測不出来则输出-1.

    这里每两条相邻的船不能相互接壤。

    思路:

    用set来维护每一段的区间。

    首先。我们最多能够放sum=(n+1)/(a+1)条船。

    这个公式是怎么来的呢? 我们能够这样想: 由于船不能接壤。所以当有k条船时,n最少为k*(a+1)-1;  然后反解就能得到答案了。

    然后我们每次攻击一个点t,就相当于把线段从中间隔开来了,我们要找到离点t近期的左右端点t1,t2,由于它们中间还插了一个t,所以就相当于t1,t2被切割开来了。

    然后当前船的数量能够由还有一个公式得到: sum=sum-(t2-t1)/(a+1)+(t-t1)/(a+1)+(t2-t)/(a+1) ;这里的意思就相当于把原先的那个区间的部分减掉,然后再加上后来分开来后的区间所能容纳的船的最大数目。

    当sum<k的时候,就说明此时alice在撒谎。

    这里查找左右端点用的是二分查找。

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    #define me rng_58
    #define maxn 200055
    set<int> st;
    set<int>::iterator it;
    int main(){
    	int n,k,a,m,i;
    	scanf("%d%d%d",&n,&k,&a);
    	scanf("%d",&m);
    	st.insert(0); 
    	st.insert(n+1);
    	int sum=(n+1)/(a+1);
    	int ans=-1;
    	for(i=1;i<=m;i++){
    		int t;
    		scanf("%d",&t);
    		it=st.upper_bound(t);
    		int t1=*it;
    		it--;				//这里为什么能减。学c++后再解答;
    		int t2=*it;
    		st.insert(t);		//这里仅仅要把t压进去就好啦!!

    !小心!。!

    sum=sum-(t1-t2)/(a+1)+(t-t2)/(a+1)+(t1-t)/(a+1); if(sum<k){ ans=i; break; } } printf("%d ",ans); } /* 5000 1660 2 20 1 100 18 102 300 81 19 25 44 88 1337 4999 1054 1203 91 16 164 914 1419 1487 */


    佩服那些可以想出来的人。Wish I can become the same like U one day!

  • 相关阅读:
    为什么ip层收到的报文可能已经设置了路由
    由socket fd泄漏想到的一些问题
    Html.DropDownLis绑定数据库
    CSS 属性备注
    获取IP
    读取TXT并筛选数据写入新建TXT
    C#打印图片
    C#生成二维码
    NPOI操作Excel
    Bootstrap
  • 原文地址:https://www.cnblogs.com/tlnshuju/p/7344686.html
Copyright © 2020-2023  润新知