今天神坑的GCPC 2013 B题啊,本来是个很简单的模拟+扫描线,却WA的不明不白
经过几个人测试,不得不说一下,CSU OJ 的编译器肯定有点问题
coj 1458
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int b,c;
struct node{
int y,m,d,h,s;
}st[5010],te[5010];
struct line{
int y,m,d,h,s,v;
}tl[10100];
int month[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
bool cmp(line w,line r)
{
if (w.y==r.y){
if (w.m==r.m){
if (w.d==r.d){
if (w.h==r.h){
if (w.s==r.s){
return w.v<r.v;
}
return w.s<r.s;
}
return w.h<r.h;
}
return w.d<r.d;
}
return w.m<r.m;
}
return w.y<r.y;
}
void init(int i)
{
int ny,nm,nd,nh,ns,t;
ns=te[i].s+c;
t=ns/60;
ns%=60;nh=te[i].h+t;
t=nh/24;
nh%=24;nd=te[i].d+t;
if (te[i].y==2016 && te[i].m==2){
if (nd>29) {t=1;nd-=29;}
else t=0;
}
else {
if (nd>month[te[i].m]){nd-=month[te[i].m];t=1;}
else t=0;
}nm=te[i].m+t;
if (nm>12) {nm-=12;t=1;}
else t=0;ny=te[i].y+t;
te[i].y=ny;te[i].m=nm;te[i].d=nd;
te[i].h=nh;te[i].s=ns;
}
int main()
{
int t;
char ch[25];
scanf("%d",&t);
while (t--){
scanf("%d%d",&b,&c);
for (int i=0;i<b;i++){
scanf("%s",ch);
scanf("%d-%d-%d %d:%d",&st[i].y,&st[i].m,&st[i].d,&st[i].h,&st[i].s);
scanf("%d-%d-%d %d:%d",&te[i].y,&te[i].m,&te[i].d,&te[i].h,&te[i].s);
init(i);
}
int cnts=0;
for (int i=0;i<b;i++){
tl[cnts++]=(line){st[i].y,st[i].m,st[i].d,st[i].h,st[i].s,1};
tl[cnts++]=(line){te[i].y,te[i].m,te[i].d,te[i].h,te[i].s,-1};
}
sort(tl,tl+cnts,cmp);
int sum=0,ans=0;
cnts=2*b; //这里如果不加,在coj上就连样例都跑不过
//cout<<"cnts= "<<cnts<<endl;
for (int k=0;k<cnts;k++){
sum+=tl[k].v;
ans=max(ans,sum);
}
printf("%d\n",ans);
cout<<"cnts= "<<cnts<<endl;
}
return 0;
}
实际那个
cnts肯定是等于2*b的,毋庸置疑,coj有个test功能,可以用来检测样例,发现cnts没错,但是就是进不去最下面那个循环,一定要加一句强制使得他等于2*b才能样例正确,但实际我不加
,在本地的codeblocks上跑的好好的,测试数据全部可以跑过去,一提交到COJ,就0msWA,说明连样例都没跑过去。,,,坑啊,我到现在还没弄明白怎么会这样,反正绝壁编译器有点什么。。
题目在前期处理比较繁琐,但是也不是很难做,然后后面用扫描线,还是聪哥想到的扫描线,我之前也做过,都没想起来用扫描线。
COJ 1453
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#define N 100010
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
using namespace std;
int n,k;
int d[N*3];
int query(int L,int R,int rt,int l,int r)
{
if (L<=l && r<=R){
return d[rt];
}
int mid=(l+r)>>1;
int ret1=0,ret2=0;
if (L<=mid) ret1=query(L,R,lson);
if (R>mid) ret2=query(L,R,rson);
return max(ret1,ret2);
}
void up(int rt)
{
d[rt]=max(d[rt<<1],d[rt<<1|1]);
}
void inserts(int loc,int val,int rt,int l,int r)
{
if (l>=r){
d[rt]=max(d[rt],val);
return;
}
int mid=(l+r)>>1;
if (loc<=mid) inserts(loc,val,lson);
else inserts(loc,val,rson);
up(rt);
}
int main()
{
int t,A;
scanf("%d",&t);
while (t--){
memset(d,0,sizeof d);
scanf("%d%d",&n,&k);
int ans=0;
for (int i=0;i<n;i++){
scanf("%d",&A);
int L= (A-k>=0 ? A-k:0);
int R=A+k;
int ans=query(L,R,1,1,N);
inserts(A,ans+1,1,1,N);
}
if (d[1]>1) printf("%d\n",d[1]);
else puts("0");
}
return 0;
}
这个题目初看有点像 LCS,而且确实可以用LCS那种
n^2方法做出来,但是此题数据量大到10万,明显不能那样做。。。哎,新手题,我居然还想复杂了,其实就是用线段树维护,边读入,边查询,边插入,就可以用
N*logN的复杂度解决了。