一维战舰(51Nod-1521)
題目
愛麗絲和鮑博喜歡玩一維戰艦的游戲。他們在一行有n個方格的紙上玩這個游戲(也就是1×n的表格)。
在游戲開始的時候,愛麗絲放k個戰艦在這個表格中,并不把具體位置告訴鮑博。每一只戰艦的形狀是 1×a 的長方形(也就是說,戰艦會占據a個連續的方格)。這些戰艦不能相互重疊,也不能相接觸。
然后鮑博會做一系列的點名。當他點到某個格子的時候,愛麗絲會告訴他那個格子是否被某只戰艦占據。如果是,就說hit,否則就說miss。
但是這兒有一個問題!愛麗絲喜歡撒謊。他每次都會告訴鮑博miss。
請你幫助鮑博證明愛麗絲撒謊了,請找出哪一步之后愛麗絲肯定撒謊了。
輸入
單組測試數據。
第一行有三個整數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編號。
輸入樣例
樣例1
11 3 3
5
4 8 6 1 11
樣例2
5 1 3
2
1 5
輸出樣例
樣例1
3
樣例2
-1
思路:桶排+模擬
利用桶排的思維,對給出的不能放置的點進行統計,然后統計當前能放的戰艦個數并與應該能放的個數進行比較,如果小于,說明撒謊,輸出位置即可
源程序
#include<iostream> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<cmath> #include<ctime> #include<algorithm> #include<utility> #include<stack> #include<queue> #include<vector> #include<set> #include<map> #define EPS 1e-9 #define PI acos(-1.0) #define INF 0x3f3f3f3f #define LL long long const int MOD = 1E9+7; const int N = 1000000+5; const int dx[] = {-1,1,0,0}; const int dy[] = {0,0,-1,1}; using namespace std; bool bucket[N]; int main() {int n,k,a,m;scanf("%d%d%d%d",&n,&k,&a,&m);bool flag=false;int num=(n+1)/(a+1);//最多放的數量for(int i=1;i<=m;i++){int x;scanf("%d",&x);bucket[x]=true;if(!flag){int left=x-1,right=x+1;while(left>=0&!bucket[left])//x左端的空余left--;while(right<=n&&!bucket[right])//x右端的空余right++;num=num-(right-left)/(a+1);//減去x左端空余到x右端空余不能放的數量num=num+(x-left)/(a+1)+(right-x)/(a+1);//加上x左右兩端空余應該能放的數量if(num<k){//如果小于最多放的數量,說明欺騙printf("%d\n",i);flag=true;}}}if(!flag)printf("-1\n");return 0; }?
總結
以上是生活随笔為你收集整理的一维战舰(51Nod-1521)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 理论基础 —— 树 —— 树的存储结构
- 下一篇: 数列分块入门 1(LibreOj-627