1. 程式人生 > >【51nod-1521】一維戰艦

【51nod-1521】一維戰艦

不能 編號 格子 每次 .html ray 長方形 http main

愛麗絲和鮑博喜歡玩一維戰艦的遊戲。他們在一行有n個方格的紙上玩這個遊戲(也就是1×n的表格)。

在遊戲開始的時候,愛麗絲放k個戰艦在這個表格中,並不把具體位置告訴鮑博。每一只戰艦的形狀是 1×a 的長方形(也就是說,戰艦會占據a個連續的方格)。這些戰艦不能相互重疊,也不能相接觸。

然後鮑博會做一系列的點名。當他點到某個格子的時候,愛麗絲會告訴他那個格子是否被某只戰艦占據。如果是,就說hit,否則就說miss。

但是這兒有一個問題!愛麗絲喜歡撒謊。他每次都會告訴鮑博miss。

請你幫助鮑博證明愛麗絲撒謊了,請找出哪一步之後愛麗絲肯定撒謊了。

Input

單組測試數據。
第一行有三個整數n,k和a(1≤n,k,a≤2*10^5),表示表格的大小,戰艦的數目,還有戰艦的大小。輸入的n,k,a保證是能夠在1×n的表格中放入k只大小為a的戰艦,並且他們之間不重疊也不接觸。
第二行是一個整數m(1≤m≤n),表示鮑博的點名次數。
第三行有m個不同的整數x1,x2,...,xm,xi是鮑博第i次點名的格子編號。格子從左到右按照1到n編號。

Output

輸出一個整數,表示最早一次能夠證明愛麗絲一定撒謊的點名編號。如果不能證明,輸出-1。點名的編號依次從1到m編號。
開始想的是每加入一個點名編號就重新統計可以放的戰艦數,實際上只需要重新計算這個編號的左右區間就可以了。很容易想到的是用set二分查找,另外set不像vector有排序的概念,所以lower_bound(st.begin(),st.end(),x)是錯誤的,正確的是st.lower_bound(x)。。。我才發現stdio.h比cstdio快了不少(之前好多卡超時的題都A惹QAQ
#include <stdio.h>
#include <set>
#include <iostream>
using namespace std;
const int N = 1005;
set<int>S;
int main()
{
    int n, k, a, m, x, ans = -1;
    bool f = 0;
    cin>>n>>k>>a>>m;
    S.insert(n+1);
    S.insert(0);
    int c = (n+1
)/(a+1);//目前一共可放艦數 for(int i=1; i<=m; i++) { scanf("%d", &x); S.insert(x); //未找到撒謊編號進入 if(!f) { set<int>::iterator it = S.lower_bound(x); set<int>::iterator it1 = it; it1--;//前一個點名編號 set<int>::iterator it3 = it; it3++;//後一個點名編號 int num = (*it3 - *it1)/(a+1);//前後編號之間可以放的戰艦數 c -= num; c += (*it-*it1)/(a+1)+(*it3-*it)/(a+1);//加入該點名編後後總共可放的戰艦數 if(c < k) { ans = i; f = 1; } } } printf("%d\n", ans); return 0; }

還有一種方法不用set也可以解決。從這個編號向左右尋找最近的兩個編號。

#include <stdio.h>

using namespace std;
const int N = 200005;
int mp[N];
int main()
{
    int n, k, a, m, x, ans = -1;
    bool f = 0;
    scanf("%d%d%d%d", &n, &k, &a, &m);
    mp[0] = 1, mp[n+1] = 1;
    int c = (n+1)/(a+1);//目前一共可放艦數
    for(int i=1; i<=m; i++)
    {
        scanf("%d", &x);
        mp[x] = 1;
        if(!f)
        {
            int j, l;
            for(j=x-1; j>=0&&!mp[j]; j--);
            for(l=x+1; l<=n&&!mp[l]; l++);
            int num = (l - j)/(a+1);
            c -= num;
            c += (x-j)/(a+1)+(l-x)/(a+1);
            if(c < k)
            {
                ans = i;
                f = 1;
            }
        }
    }
    printf("%d\n", ans);
    return 0;
}

【51nod-1521】一維戰艦