题目地址: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 }