题目地址: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 }
01-10 15:39