Color the ball
Time Limit : 9000/3000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 9 Accepted Submission(s) : 4
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
Input
当N = 0,输入结束。
Output
Sample Input
3 1 1 2 2 3 3 3 1 1 1 2 1 3 0
Sample Output
1 1 1 3 2 1
Author
Source
#include<iostream>
using namespace std;
int s[100002];
int main(){
int n;
int a,b;
while(scanf("%d",&n)!=EOF && n){
memset(s,0,sizeof(s));
for(int i=1;i<=n;i++){
scanf("%d%d",&a,&b);
for(int j=a;j<=b;j++)
s[j]++;
}
for(int i=1;i<n;i++)
printf("%d ",s[i]);
printf("%d\n",s[n]);
}
return 0;
}
算了,还是百度一下吧,下面是网上一个朋友的代码,下面是他的代码和他的解析。。。
//HDOJ 1556
//原本以为是线段树 整体优化 提交两次还是TLE
//线段树 也应该能过 可能是我写得代码挫了
//后来发现可以通过递推得到
//开辟三个数组空间,一个记录每个点作为涂色起点的次数,一个记录每个点作为涂色终点的次数
//还有一个数组num,保存计算得到的每个点涂色次数
//可以有两种递推思路 一种自上而下 一种自下而上
//例如自上而下 首先保存num[1]=start[1]; 因为1是边界点 所以涂色次数就等于作为起点次数
//然后看 i=2 如果 i=1 时候start[1]==end[1] 说明没有跨越1 2 的涂色过程
//也就是说,这时候的 start[2]就是 num[2]
//否则 如果i=1 时候 start[1]!=end[1] 说明有num[1]-end[1] 次涂色不是以1 结束的,那么至少是以2结束的
//所以 i=2 位置作为终点或者中间点涂色进行了num[1]-end[1] 次,再加上作为起点位置的start[2]次,就是总共的涂色次数
//其实另一种自下而上也是同样的思路,递推过程是逆序的
593 ms 1440 kb
#include<iostream>
using namespace std;
int start[100001],end[100001],num[100001];
int main(){
int n,i,a,b;
while(scanf("%d",&n)==1 && n){
memset(start,0,sizeof(start));
memset(end,0,sizeof(end));
memset(num,0,sizeof(num));
for(i=1;i<=n;i++){
scanf("%d%d",&a,&b);
start[a]++;
end[b]++;
}
num[1]=start[1];
for(i=2;i<=n;i++)
num[i]=start[i]+num[i-1]-end[i-1];
for(i=1;i<n;i++)
printf("%d ",num[i]);
printf("%d\n",num[n]);
}
return 0;
}
//一个学期后复习的时候再来做,水过
#include<iostream>
#include<cstring>
using namespace std;
int tree[100005],n;
int lowbit(int x){
return x&(-x);
}
void update(int i,int val){
while(i<=n){
tree[i]+=val;
i+=lowbit(i);
}
}
int getsum(int i){
int s=0;
while(i>0){
s+=tree[i];
i-=lowbit(i);
}
return s;
}
int main(){
int a,b;
while(scanf("%d",&n)==1 && n){
memset(tree,0,sizeof(tree));
for(int i=1;i<=n;i++){
scanf("%d%d",&a,&b);
update(a,1); //想象一下,将a位置加1,将b+1后的减1,后面结果输出时输出前面所有项的和
update(b+1,-1);
}
for(int i=1;i<n;i++)
printf("%d ",getsum(i));//第i个气球的颜色就等于前i项的和
printf("%d\n",getsum(n));
}
//system("pause");
return 0;
}