Codeforces Round #288 (Div. 2) C. Anya and Ghosts
2015-02-05 11:23
253 查看
题意:有m个鬼,每个鬼到访1秒,要求鬼到访的这一秒有r根蜡烛是亮的。
每根蜡烛点燃需要1秒,可以亮t秒。问最少需要点燃多少根蜡烛。
如果不能满足所有鬼来时都有r根蜡烛是亮的,则输出-1。
若x秒时点燃蜡烛,则x+1到x+t秒该蜡烛照亮。
可以再任何整数时刻点燃蜡烛。
分析:
如果t<r则不可能有r根蜡烛同时照亮,否则一定可以满足条件。
在鬼来前点亮,越靠近鬼来的时刻越好。如果蜡烛不够,则从鬼来的时刻ghost[i]-1向前递推
t秒,看要补几根蜡烛。
这里要补的蜡烛一定是靠近鬼的,因为先点的蜡烛肯定已经燃尽了。
这样只要采用贪心策略加模拟就可以了。
由于鬼来的时间可能为1-300,蜡烛的数目为1-300,则可能在之前就把蜡烛点燃。为了方便处理,
把鬼来的时间推迟300s。这样点蜡烛的时间就可以在正整数范围0-600中确定了。
还看了2种很值得借鉴的代码实现。
其中一种思路差不多 来源于http://blog.csdn.net/logzhangrui/article/details/43274051
另外一种是在codeforces上看到的。
他判断不可能的情况是 先把所有时刻0-600都放蜡烛。然后扫一遍尝试着减少
每个时刻的蜡烛,看是否仍然能满足条件。若能则灭掉蜡烛,否则点亮。一边
判断一边统计。
以上2种思路中各个时刻的蜡烛只有点亮和熄灭两种,而没有考虑有几根亮。
这种简化问题的转换值得思考(*^__^*) 嘻嘻……
每根蜡烛点燃需要1秒,可以亮t秒。问最少需要点燃多少根蜡烛。
如果不能满足所有鬼来时都有r根蜡烛是亮的,则输出-1。
若x秒时点燃蜡烛,则x+1到x+t秒该蜡烛照亮。
可以再任何整数时刻点燃蜡烛。
分析:
如果t<r则不可能有r根蜡烛同时照亮,否则一定可以满足条件。
在鬼来前点亮,越靠近鬼来的时刻越好。如果蜡烛不够,则从鬼来的时刻ghost[i]-1向前递推
t秒,看要补几根蜡烛。
这里要补的蜡烛一定是靠近鬼的,因为先点的蜡烛肯定已经燃尽了。
这样只要采用贪心策略加模拟就可以了。
由于鬼来的时间可能为1-300,蜡烛的数目为1-300,则可能在之前就把蜡烛点燃。为了方便处理,
把鬼来的时间推迟300s。这样点蜡烛的时间就可以在正整数范围0-600中确定了。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cstdlib> #include<cmath> #include<vector> #include<queue> #include<map> using namespace std; typedef long long ll; int a[630],time[630]; int main() { int m,t,r; while(~scanf("%d%d%d",&m,&t,&r)) { memset(time,0,sizeof(time)); for(int i=1;i<=m;i++) { scanf("%d",&a[i]); a[i] += 300; } if(r>t) { puts("-1"); continue; } for(int i=1;i<=m;i++) { int check = 0; for(int j=a[i]-1;j>=a[i]-t;j--) { if(time[j]==1) check++; } for(int j=a[i]-1;j>=(a[i]-(r-check));j--) time[j] = 1; } int ans = 0; for(int i=0;i<=600;i++) if(time[i]==1) ans++; cout<<ans<<endl; } return 0; }
还看了2种很值得借鉴的代码实现。
其中一种思路差不多 来源于http://blog.csdn.net/logzhangrui/article/details/43274051
#include<stdio.h> #include<string.h> int main() { int ghost[1010],time[1010]; int m,t,r; while(scanf("%d%d%d",&m,&t,&r)!=EOF) { memset(ghost,0,sizeof(ghost)); memset(time,0,sizeof(time)); for(int i=1;i<=m;i++) { scanf("%d",&ghost[i]); } if(r>t) { printf("-1\n"); return 0; } int sum=0; for(int i=1;i<=m;i++) { for(int j=ghost[i];r-time[ghost[i]]>0;j--) { sum++; for(int k=0;k<t;k++) if(k+j>=0) time[k+j]++; } } printf("%d\n",sum); } return 0; }
另外一种是在codeforces上看到的。
他判断不可能的情况是 先把所有时刻0-600都放蜡烛。然后扫一遍尝试着减少
每个时刻的蜡烛,看是否仍然能满足条件。若能则灭掉蜡烛,否则点亮。一边
判断一边统计。
#include <iostream> #include <cstdio> #include <cstdlib> using namespace std; const int N = 2000; int a ; int n, r, t; int b ; const int T = 630; int ans = T; bool check() { for (int i = 0; i < n; i++) { int cnt = 0; for (int j = a[i] - t; j < a[i]; j++) cnt += b[j]; if (cnt < r) return false; } return true; } int main() { scanf("%d%d%d", &n, &t, &r); for (int i = 0; i < n; i++) { scanf("%d", &a[i]); a[i] += 300; } for (int i = 0; i < T; i++) b[i] = 1; if (!check()) { printf("-1\n"); return 0; } for (int i = T - 1; i >= 0; i--) { b[i] = 0; if (!check()) b[i] = 1; ans -= (1 - b[i]); } printf("%d\n", ans); return 0; }
以上2种思路中各个时刻的蜡烛只有点亮和熄灭两种,而没有考虑有几根亮。
这种简化问题的转换值得思考(*^__^*) 嘻嘻……
相关文章推荐
- C. Anya and Ghosts( Codeforces Round #288 (Div. 2))
- Codeforces Round #288 (Div. 2) C. Anya and Ghosts
- C. Anya and Ghosts(Codeforces Round #288 (Div. 2))
- 贪心+模拟 Codeforces Round #288 (Div. 2) C. Anya and Ghosts
- Codeforces Round #288 (Div. 2)C. Anya and Ghosts(模拟+贪心)
- Codeforces Round #288 (Div. 2)C. Anya and Ghosts
- Codeforces Round #288 (Div. 2) C. Anya and Ghosts 模拟
- Codeforces Round #288 (Div. 2) C. Anya and Ghosts
- Codeforces Round #288 (Div. 2) C. Anya and Ghosts 贪心
- Codeforces Round #288 (Div. 2)---C. Anya and Ghosts
- Codeforces Round #288 (Div. 2) C. Anya and Ghosts(贪心)
- Codeforces Round #288 (Div. 2) C. Anya and Ghosts
- C. Anya and Ghosts(Codeforces Round #288(div2)
- Codeforces Round #288 (Div. 2) C. Anya and Ghosts 模拟 贪心
- codeforces--C - Anya and Ghosts(贪心)
- codeforces--C - Anya and Ghosts(贪心+模拟)
- Codeforces Round #297 (Div. 2) 525E Anya and Cubes(dfs)
- Codeforces 508C Anya and Ghosts【贪心】
- (又FST在long long!!)Codeforces Round #293 (Div. 2)C. Anya and Smartphone
- Codeforces 508C Anya and Ghosts