51Nod - 1521 一維戰艦
阿新 • • 發佈:2017-05-18
一行 喜歡 con output 相互 pre 距離 邊界 class
Output
51Nod - 1521 一維戰艦
愛麗絲和鮑博喜歡玩一維戰艦的遊戲。他們在一行有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編號。
輸出一個整數,表示最早一次能夠證明愛麗絲一定撒謊的點名編號。如果不能證明,輸出-1。點名的編號依次從1到m編號。Input示例
樣例1 11 3 3 5 4 8 6 1 11 樣例2 5 1 3 2 1 5Output示例
樣例輸出1 3 樣例輸出2 -1
題解:
前幾天看到題目實在是沒有思路,然後網絡搜了下,現在回頭在做。
1, 在一段距離能放戰艦的數量是: (r - l)/(a + 1); 其中 r l 是開邊界。
2, 那麽中間被一個元素隔開,兩端孤立的距離段則是: (r - mid)/(a + 1), (mid - l)/(a + 1)
所以,按照上面的思路,可以進行計算。
#include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> using namespace std; const int MAXN = 200000 + 5; int vis[MAXN], x[MAXN]; int main(){ int n, k, a, m, l, r, cur, ans; while(scanf("%d %d %d", &n, &k, &a) != EOF){ scanf("%d", &m); for(int i=0; i<m; ++i){ scanf("%d", &x[i]); } memset(vis, 0, sizeof(vis)); ans = -1; cur = (n + 1)/(a+1); for(int i=0; i<m; ++i){ vis[ x[i] ] = 1; l = x[i]-1; r = x[i]+1; while(l >=1 && vis[l] == 0){ l--; } while(r <= n && vis[r] == 0){ r++; } cur -= (r-l)/(a+1) - (r-x[i])/(a+1) - (x[i]-l)/(a+1); if(cur < k){ ans = i + 1; break; } } printf("%d\n", ans ); } return 0; }
51Nod - 1521 一維戰艦