题目地址:http://codeforces.com/contest/1256/problem/C
题意:一条有n个格子水的河,要跳到对岸去,里面有数量小于等于n块木板,没部分木板都有自己的集合,各个集合的木板都是要连在一起的,木板不能重合放,一次能跳(1,d)的距离,求能不能跳到对面,能的话将木板的放置方法打印出来。
思路:先将木板都放在右边,然后每次跳d的距离,每次都将一个集合的木板转移到跳的位置即可,具体实现看代码
AC代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 typedef long long ll; 7 const int N=1005; 8 void sol(){ 9 int n,m,d; 10 int a[N]={0},b[N]={0},c[N]={0},s[N]={0}; 11 cin>>n>>m>>d; 12 for(int i=1;i<=m;i++){ 13 cin>>c[i]; 14 b[i]=b[i-1]+c[i]; 15 } 16 int lst=d; //开始时直接跳到d位置 17 for(int i=1;i<=m;i++){ 18 int fir=n+1-(b[m]-b[i-1]); 19 s[i]=min(fir,lst); 20 //木板开始都在最右边,依次向左递,看位置与每次跳d格的那个更小, 21 //更小的为fir时说明向左递的木板已经够了,后面就可以一格一格跳了 22 lst=s[i]+c[i]+d-1; 23 } 24 if(lst<=n) cout<<"NO"<<endl; //说明每次跳d都不能过,那肯定是跳不过去了 25 else { 26 cout<<"YES"<<endl; 27 for(int i=1;i<=m;i++) 28 for(int j=0;j<c[i];j++) 29 a[s[i]+j]=i; 30 for(int i=1;i<=n;i++){ 31 cout<<a[i]; 32 if(i!=n) cout<<" "; 33 else cout<<endl; 34 } 35 } 36 } 37 int main(){ 38 sol(); 39 return 0; 40 }