p1166
拿到题后先分析题意:求n个牛棚中能够扩张的数量.
然后看数据范围确定解法:n<=25000不能写n^2枚举.坐标范围是[0,1000000],不论是时间还是空间不能写地图标记flag后判断...
考虑如果只有左右两个墙,问你能像左右拓展的牛棚数量.这个时候发现还是不能写整个[0,1000000]范围.因为可能会有两个边在同一个数列上并且这时候不会判断大小.能否写链表呢?每个i后面跟一串链表记录所有边,然后再跑双指针?貌似可以.
考虑这个代码复杂度极高的很捞的算法的出现过程.首先只有两个墙的思想是离散化的表现.因为能否扩张只需要考虑两两边的关系对吧.然后那个很捞的链表根本没用啊,为什么不写sort然后跑双指针呢?
好了A了.
bool flag[25010]; struct shu { int x,ay,by; int i; }a[50010]; bool Orz(shu x,shu y) { if(x.x==y.x) return x.ay<y.ay; return x.x<y.x; } struct heng { int y,ax,bx; int i; }b[50010]; bool orz(heng x,heng y) { if(x.y==y.y)return x.ax<y.ax; else return x.y<y.y; } int n,ans; int i,f,ax,ay,bx,by,zuo,you; int main() { //freopen("123.in","r",stdin); n=read(); for(i=1;i<=n;i++) { ax=read(); ay=read(); bx=read(); by=read(); f++; a[f].x=b[f].ax=ax; b[f].bx=bx; a[f].ay=b[f].y=ay; a[f].by=by; a[f].i=b[f].i=i; f++; b[f].ax=ax; b[f].bx=a[f].x=bx; a[f].ay=ay; b[f].y=a[f].by=by; a[f].i=b[f].i=i; } sort(a+1,a+1+f,Orz); sort(b+1,b+1+f,orz); for(zuo=you=1;zuo<=2*n;) { while(a[you+1].x==a[you].x) you++; for(i=zuo;i<you;i++) { for(f=i+1;f<=you;f++) if(a[i].by>=a[f].ay) flag[a[i].i]=flag[a[f].i]=1; else break; } zuo=you=you+1; } for(zuo=you=1;zuo<=2*n;) { while(b[you+1].y==b[you].y) you++; for(i=zuo;i<you;i++) { for(f=i+1;f<=you;f++) if(b[i].bx>=b[f].ax) flag[b[i].i]=flag[b[f].i]=1; else break; } zuo=you=you+1; } for(i=1,ans=n;i<=n;i++) ans-=flag[i]; cout<<ans; return 0; }