愛麗絲和鮑博喜歡玩一維戰艦的遊戲。他們在一行有n個方格的紙上玩這個遊戲(也就是1×n的表格)。html
在遊戲開始的時候,愛麗絲放k個戰艦在這個表格中,並不把具體位置告訴鮑博。每一隻戰艦的形狀是 1×a 的長方形(也就是說,戰艦會佔據a個連續的方格)。這些戰艦不能相互重疊,也不能相接觸。ios
而後鮑博會作一系列的點名。當他點到某個格子的時候,愛麗絲會告訴他那個格子是否被某隻戰艦佔據。若是是,就說hit,不然就說miss。測試
可是這兒有一個問題!愛麗絲喜歡撒謊。他每次都會告訴鮑博miss。spa
請你幫助鮑博證實愛麗絲撒謊了,請找出哪一步以後愛麗絲確定撒謊了。code
單組測試數據。 第一行有三個整數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編號。
輸出一個整數,表示最先一次可以證實愛麗絲必定撒謊的點名編號。若是不能證實,輸出-1。點名的編號依次從1到m編號。
#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也能夠解決。從這個編號向左右尋找最近的兩個編號。htm
#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; }