/*
 * Author : Remilia Scarlet
 */

// #pragma comment(linker, "/STACK:102400000,102400000")

#include <bits/stdc++.h>

#define For(i,l,r) for(int _r=r,i=l;i<=_r;++i)
#define rep(i,l,r) for(int _r=r,i=l;i<_r;++i)
#define dto(i,r,l) for(int _l=l,i=r;i>=_l;--i)
#define x first
#define y second
#define pb push_back
#define mk make_pair
#define oo (c=getchar())
#define SZ(V) (int(V.size()))
#define ALL(V) V.begin(),V.end()

using namespace std;

typedef double db;
typedef long long LL;
typedef pair<int ,int> PII;
typedef vector<int> VI;
typedef complex<db> cpx;
typedef vector<PII> VII;
// typedef __int128 bigint;

int ran(){return (rand()<<15)+rand();}

int IN(){
	int x=0;char c;
	for(;oo<48 && c^'-' || c>57;);bool f=c=='-';if(f)oo;
	for(;c>47 && c<58;oo)x=(x<<1)+(x<<3)+c-48;return f?-x:x;
}
void print(int x,char en='\n'){
	printf("%d",x);if(en)putchar(en);
}

void hello(){
	freopen("remi.in","r",stdin);
//	freopen("remi.out","w",stdout);
//	srand(time(0));
}

const db eps = 1e-12;

int dcmp(db x, db y){
	return fabs(x-y)<eps?0:x<y?-1:1;
}

struct ww{
	db x,y;
	db polar(){
		return atan2(y,x);
	}
};

struct fenwick_tree{
	int lim,t[200010];
	void pret(int n){
		For(i,1,lim)t[i] = 0;
		lim = n;
		assert(lim<200010);
	}
	void add(int x, int y){
		assert(x>0);
		for(;x<=lim;x+=x&-x)t[x]+=y;
	}
	int qs(int x){
		if(!x)return 0;
		assert(x>0);
		int an = 0;
		for(;x;x-=x&-x)an+=t[x];
		return an;
	}
}ds;

int n,m;
db k[50010],b[50010],fi[50010];

LL count(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 4*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	ds.pret(c);
	LL res = 0;
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				res += ds.qs(id[k]-1)-ds.qs(fi[li[k].y]);
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				ds.add(id[k],1);
				ds.add(fi[li[k].y],-1);
			}
		}i=j;
	}
	for(auto it:li)fi[it.y] = 0;
	return res;
}

VI seg_list[524289];

db solve(int i,int j){
	if(dcmp(k[i],k[j]) == 0)return 0;
	db x = (b[j]-b[i])/(k[i]-k[j]);
	db y = k[i]*x+b[i];
	return sqrt(x*x+y*y);
}

db sumup(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 4*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	db res = 0;
	int lim = 1;
	for(;lim<c+2;lim<<=1);
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				int line1 = li[k].y;
				for(int u = lim+fi[li[k].y];u;u>>=1)
					for(int line2:seg_list[u]){
						db dis = solve(line1,line2);
						res += dis;
					}
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				int ll = lim + fi[li[k].y]-1, rr = lim+id[k]+1;
				for(;ll^rr^1;ll>>=1,rr>>=1){
					if(~ll&1)seg_list[ll^1].pb(li[k].y);
					if(rr&1) seg_list[rr^1].pb(li[k].y);
				}
			}
		}i=j;
	}
	return res;
}

void Main(){
	db ll = 0, rr = 3e9;
	rep(tc,0,100){
		db mm = (ll+rr)*.5;
		if(count(mm)<=m)ll = mm;else rr = mm;
	}
	LL cnt = count(ll);
	assert(cnt<=m);
	assert(count(ll+eps)>=m);
	db ans = sumup(ll);
	ans += (m-cnt)*ll;
	printf("%.20lf\n",ans);
}

int main(int argc, char* argv[]){
	// hello();
	n = IN();
	ww P;
	P.x = IN()/1000., P.y = IN()/1000.;
	m = IN();
	For(i,1,n)k[i] = IN()/1000., b[i] = IN()/1000.-P.y+k[i]*P.x;
	Main();
}


/*
 * Author : Remilia Scarlet
 */

// #pragma comment(linker, "/STACK:102400000,102400000")

#include <bits/stdc++.h>

#define For(i,l,r) for(int _r=r,i=l;i<=_r;++i)
#define rep(i,l,r) for(int _r=r,i=l;i<_r;++i)
#define dto(i,r,l) for(int _l=l,i=r;i>=_l;--i)
#define x first
#define y second
#define pb push_back
#define mk make_pair
#define oo (c=getchar())
#define SZ(V) (int(V.size()))
#define ALL(V) V.begin(),V.end()

using namespace std;

typedef long double db;
typedef long long LL;
typedef pair<int ,int> PII;
typedef vector<int> VI;
typedef complex<db> cpx;
typedef vector<PII> VII;
// typedef __int128 bigint;

int ran(){return (rand()<<15)+rand();}

int IN(){
	int x=0;char c;
	for(;oo<48 && c^'-' || c>57;);bool f=c=='-';if(f)oo;
	for(;c>47 && c<58;oo)x=(x<<1)+(x<<3)+c-48;return f?-x:x;
}
void print(int x,char en='\n'){
	printf("%d",x);if(en)putchar(en);
}

void hello(){
	freopen("remi.in","r",stdin);
//	freopen("remi.out","w",stdout);
//	srand(time(0));
}

const db eps = 1e-16;

int dcmp(db x, db y){
	return fabs(x-y)<eps?0:x<y?-1:1;
}

struct ww{
	db x,y;
	db polar(){
		return atan2(y,x);
	}
};

struct fenwick_tree{
	int lim,t[200010];
	void pret(int n){
		For(i,1,lim)t[i] = 0;
		lim = n;
		assert(lim<200010);
	}
	void add(int x, int y){
		assert(x>0);
		for(;x<=lim;x+=x&-x)t[x]+=y;
	}
	int qs(int x){
		if(!x)return 0;
		assert(x>0);
		int an = 0;
		for(;x;x-=x&-x)an+=t[x];
		return an;
	}
}ds;

int n,m;
db k[50010],b[50010],fi[50010];

LL count(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 4*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	ds.pret(c);
	LL res = 0;
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				res += ds.qs(id[k]-1)-ds.qs(fi[li[k].y]);
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				ds.add(id[k],1);
				ds.add(fi[li[k].y],-1);
			}
		}i=j;
	}
	for(auto it:li)fi[it.y] = 0;
	return res;
}

VI seg_list[524289];

db solve(int i,int j){
	assert(dcmp(k[i],k[j]));
	if(dcmp(k[i],k[j]) == 0)return 0;
	db x = (b[j]-b[i])/(k[i]-k[j]);
	db y = k[i]*x+b[i];
	return sqrt(x*x+y*y);
}

auto sumup(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 4*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	db res = 0;
	int cnt = 0;
	int lim = 1;
	for(;lim<c+2;lim<<=1);
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				int line1 = li[k].y;
				for(int u = lim+fi[li[k].y];u;u>>=1)
					for(int line2:seg_list[u]){
						db dis = solve(line1,line2);
						res += dis;
						++cnt;
					}
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				int ll = lim + fi[li[k].y], rr = lim+id[k];
				for(;ll^rr^1;ll>>=1,rr>>=1){
					if(~ll&1)seg_list[ll^1].pb(li[k].y);
					if(rr&1) seg_list[rr^1].pb(li[k].y);
				}
			}
		}i=j;
	}
	return mk(res,cnt);
}

void Main(){
	db ll = 0, rr = 3e9;
	rep(tc,0,100){
		db mm = (ll+rr)*.5;
		if(count(mm)<=m)ll = mm;else rr = mm;
	}
	auto it = sumup(ll);
	assert(it.y<=m);
	printf("%.20lf\n",double(it.x+(m-it.y)*ll));
}

int main(int argc, char* argv[]){
	// hello();
	n = IN();
	ww P;
	P.x = IN()/1000., P.y = IN()/1000.;
	m = IN();
	For(i,1,n)k[i] = IN()/1000., b[i] = IN()/1000.-P.y+k[i]*P.x;
	Main();
}


/*
 * Author : Remilia Scarlet
 */

// #pragma comment(linker, "/STACK:102400000,102400000")

#include <bits/stdc++.h>

#define For(i,l,r) for(int _r=r,i=l;i<=_r;++i)
#define rep(i,l,r) for(int _r=r,i=l;i<_r;++i)
#define dto(i,r,l) for(int _l=l,i=r;i>=_l;--i)
#define x first
#define y second
#define pb push_back
#define mk make_pair
#define oo (c=getchar())
#define SZ(V) (int(V.size()))
#define ALL(V) V.begin(),V.end()

using namespace std;

typedef double db;
typedef long long LL;
typedef pair<int ,int> PII;
typedef vector<int> VI;
typedef complex<db> cpx;
typedef vector<PII> VII;
// typedef __int128 bigint;

int ran(){return (rand()<<15)+rand();}

int IN(){
	int x=0;char c;
	for(;oo<48 && c^'-' || c>57;);bool f=c=='-';if(f)oo;
	for(;c>47 && c<58;oo)x=(x<<1)+(x<<3)+c-48;return f?-x:x;
}
void print(int x,char en='\n'){
	printf("%d",x);if(en)putchar(en);
}

void hello(){
	freopen("remi.in","r",stdin);
//	freopen("remi.out","w",stdout);
//	srand(time(0));
}

const db eps = 1e-12;

int dcmp(db x, db y){
	return fabs(x-y)<eps?0:x<y?-1:1;
}

struct ww{
	db x,y;
	db polar(){
		return atan2(y,x);
	}
};

struct fenwick_tree{
	int lim,t[200010];
	void pret(int n){
		For(i,1,lim)t[i] = 0;
		lim = n;
		assert(lim<200010);
	}
	void add(int x, int y){
		assert(x>0);
		for(;x<=lim;x+=x&-x)t[x]+=y;
	}
	int qs(int x){
		if(!x)return 0;
		assert(x>0);
		int an = 0;
		for(;x;x-=x&-x)an+=t[x];
		return an;
	}
}ds;

int n,m;
db k[50010],b[50010],fi[50010];

LL count(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 2*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	ds.pret(c);
	LL res = 0;
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				res += ds.qs(id[k]-1)-ds.qs(fi[li[k].y]);
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				ds.add(id[k],1);
				ds.add(fi[li[k].y],-1);
			}
		}i=j;
	}
	for(auto it:li)fi[it.y] = 0;
	return res;
}

VI seg_list[524289];

db solve(int i,int j){
	if(dcmp(k[i],k[j]) == 0)return 0;
	db x = (b[j]-b[i])/(k[i]-k[j]);
	db y = k[i]*x+b[i];
	return sqrt(x*x+y*y);
}

db sumup(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 2*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	db res = 0;
	int lim = 1;
	for(;lim<c+2;lim<<=1);
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				int line1 = li[k].y;
				for(int u = lim+fi[li[k].y];u;u>>=1)
					for(int line2:seg_list[u]){
						db dis = solve(line1,line2);
						assert(dcmp(dis,R)==-1);
						res += dis;
					}
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				int ll = lim + fi[li[k].y]-1, rr = lim+id[k]+1;
				for(;ll^rr^1;ll>>=1,rr>>=1){
					if(~ll&1)seg_list[ll^1].pb(li[k].y);
					if(rr&1) seg_list[rr^1].pb(li[k].y);
				}
			}
		}i=j;
	}
	return res;
}

void Main(){
	db ll = 0, rr = 3e9;
	rep(tc,0,100){
		db mm = (ll+rr)*.5;
		if(count(mm)<=m)ll = mm;else rr = mm;
	}
	LL cnt = count(ll);
	if(n==2000)print(cnt),printf("%lf\n",ll);
	assert(cnt<=m && dcmp(ll,rr)==0);
	db ans = sumup(ll);
	ans += (m-cnt)*ll;
	printf("%.20lf\n",ans);
}

int main(int argc, char* argv[]){
	// hello();
	n = IN();
	ww P;
	P.x = IN()/1000., P.y = IN()/1000.;
	m = IN();
	For(i,1,n)k[i] = IN()/1000., b[i] = IN()/1000.-P.y+k[i]*P.x;
	Main();
}


/*
 * Author : Remilia Scarlet
 */

// #pragma comment(linker, "/STACK:102400000,102400000")

#include <bits/stdc++.h>

#define For(i,l,r) for(int _r=r,i=l;i<=_r;++i)
#define rep(i,l,r) for(int _r=r,i=l;i<_r;++i)
#define dto(i,r,l) for(int _l=l,i=r;i>=_l;--i)
#define x first
#define y second
#define pb push_back
#define mk make_pair
#define oo (c=getchar())
#define SZ(V) (int(V.size()))
#define ALL(V) V.begin(),V.end()

using namespace std;

typedef double db;
typedef long long LL;
typedef pair<int ,int> PII;
typedef vector<int> VI;
typedef complex<db> cpx;
typedef vector<PII> VII;
// typedef __int128 bigint;

int ran(){return (rand()<<15)+rand();}

int IN(){
	int x=0;char c;
	for(;oo<48 && c^'-' || c>57;);bool f=c=='-';if(f)oo;
	for(;c>47 && c<58;oo)x=(x<<1)+(x<<3)+c-48;return f?-x:x;
}
void print(int x,char en='\n'){
	printf("%d",x);if(en)putchar(en);
}

void hello(){
	freopen("remi.in","r",stdin);
//	freopen("remi.out","w",stdout);
//	srand(time(0));
}

const db eps = 1e-12;

int dcmp(db x, db y){
	return fabs(x-y)<eps?0:x<y?-1:1;
}

struct ww{
	db x,y;
	db polar(){
		return atan2(y,x);
	}
};

struct fenwick_tree{
	int lim,t[200010];
	void pret(int n){
		For(i,1,lim)t[i] = 0;
		lim = n;
		assert(lim<200010);
	}
	void add(int x, int y){
		assert(x>0);
		for(;x<=lim;x+=x&-x)t[x]+=y;
	}
	int qs(int x){
		if(!x)return 0;
		assert(x>0);
		int an = 0;
		for(;x;x-=x&-x)an+=t[x];
		return an;
	}
}ds;

int n,m;
db k[50010],b[50010],fi[50010];

LL count(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 4*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	ds.pret(c);
	LL res = 0;
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				res += ds.qs(id[k]-1)-ds.qs(fi[li[k].y]);
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				ds.add(id[k],1);
				ds.add(fi[li[k].y],-1);
			}
		}i=j;
	}
	for(auto it:li)fi[it.y] = 0;
	return res;
}

VI seg_list[524289];

db solve(int i,int j){
	assert(dcmp(k[i],k[j]));
	if(dcmp(k[i],k[j]) == 0)return 0;
	db x = (b[j]-b[i])/(k[i]-k[j]);
	db y = k[i]*x+b[i];
	return sqrt(x*x+y*y);
}

auto sumup(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 4*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	db res = 0;
	int cnt = 0;
	int lim = 1;
	for(;lim<c+2;lim<<=1);
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				int line1 = li[k].y;
				for(int u = lim+fi[li[k].y];u;u>>=1)
					for(int line2:seg_list[u]){
						db dis = solve(line1,line2);
						res += dis;
						++cnt;
					}
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				int ll = lim + fi[li[k].y], rr = lim+id[k];
				for(;ll^rr^1;ll>>=1,rr>>=1){
					if(~ll&1)seg_list[ll^1].pb(li[k].y);
					if(rr&1) seg_list[rr^1].pb(li[k].y);
				}
			}
		}i=j;
	}
	return mk(res,cnt);
}

void Main(){
	db ll = 0, rr = 3e9;
	rep(tc,0,100){
		db mm = (ll+rr)*.5;
		if(count(mm)<=m)ll = mm;else rr = mm;
	}
	auto it = sumup(ll);
	assert(it.y<=m);
	printf("%.20lf\n",it.x+(m-it.y)*ll);
}

int main(int argc, char* argv[]){
	// hello();
	n = IN();
	ww P;
	P.x = IN()/1000., P.y = IN()/1000.;
	m = IN();
	For(i,1,n)k[i] = IN()/1000., b[i] = IN()/1000.-P.y+k[i]*P.x;
	Main();
}


/*
 * Author : Remilia Scarlet
 */

// #pragma comment(linker, "/STACK:102400000,102400000")

#include <bits/stdc++.h>

#define For(i,l,r) for(int _r=r,i=l;i<=_r;++i)
#define rep(i,l,r) for(int _r=r,i=l;i<_r;++i)
#define dto(i,r,l) for(int _l=l,i=r;i>=_l;--i)
#define x first
#define y second
#define pb push_back
#define mk make_pair
#define oo (c=getchar())
#define SZ(V) (int(V.size()))
#define ALL(V) V.begin(),V.end()

using namespace std;

typedef double db;
typedef long long LL;
typedef pair<int ,int> PII;
typedef vector<int> VI;
typedef complex<db> cpx;
typedef vector<PII> VII;
// typedef __int128 bigint;

int ran(){return (rand()<<15)+rand();}

int IN(){
	int x=0;char c;
	for(;oo<48 && c^'-' || c>57;);bool f=c=='-';if(f)oo;
	for(;c>47 && c<58;oo)x=(x<<1)+(x<<3)+c-48;return f?-x:x;
}
void print(int x,char en='\n'){
	printf("%d",x);if(en)putchar(en);
}

void hello(){
	freopen("remi.in","r",stdin);
//	freopen("remi.out","w",stdout);
//	srand(time(0));
}

const db eps = 1e-12;

int dcmp(db x, db y){
	return fabs(x-y)<eps?0:x<y?-1:1;
}

struct ww{
	db x,y;
	db polar(){
		return atan2(y,x);
	}
};

struct fenwick_tree{
	int lim,t[200010];
	void pret(int n){
		For(i,1,lim)t[i] = 0;
		lim = n;
		assert(lim<200010);
	}
	void add(int x, int y){
		assert(x>0);
		for(;x<=lim;x+=x&-x)t[x]+=y;
	}
	int qs(int x){
		if(!x)return 0;
		assert(x>0);
		int an = 0;
		for(;x;x-=x&-x)an+=t[x];
		return an;
	}
}ds;

int n,m;
db k[50010],b[50010],fi[50010];

LL count(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 4*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	ds.pret(c);
	LL res = 0;
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				res += ds.qs(id[k]-1)-ds.qs(fi[li[k].y]);
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				ds.add(id[k],1);
				ds.add(fi[li[k].y],-1);
			}
		}i=j;
	}
	for(auto it:li)fi[it.y] = 0;
	return res;
}

VI seg_list[524289];

db solve(int i,int j){
	assert(dcmp(k[i],k[j]));
	if(dcmp(k[i],k[j]) == 0)return 0;
	db x = (b[j]-b[i])/(k[i]-k[j]);
	db y = k[i]*x+b[i];
	return sqrt(x*x+y*y);
}

auto sumup(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 4*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	db res = 0;
	int cnt = 0;
	int lim = 1;
	for(;lim<c+2;lim<<=1);
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				int line1 = li[k].y;
				for(int u = lim+fi[li[k].y];u;u>>=1)
					for(int line2:seg_list[u]){
						db dis = solve(line1,line2);
						res += dis;
						++cnt;
					}
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				int ll = lim + fi[li[k].y], rr = lim+id[k];
				for(;ll^rr^1;ll>>=1,rr>>=1){
					if(~ll&1)seg_list[ll^1].pb(li[k].y);
					if(rr&1) seg_list[rr^1].pb(li[k].y);
				}
			}
		}i=j;
	}
	return mk(res,cnt);
}

void Main(){
	db ll = 0, rr = 3e9;
	rep(tc,0,100){
		db mm = (ll+rr)*.5;
		if(count(mm)<=m)ll = mm;else rr = mm;
	}
	auto it = sumup(ll);
	assert(it.y<=m);
	printf("%.20lf\n",it.x+(m-it.y)*ll);
}

int main(int argc, char* argv[]){
	// hello();
	n = IN();
	ww P;
	P.x = IN()/1000., P.y = IN()/1000.;
	m = IN();
	For(i,1,n)k[i] = IN()/1000., b[i] = IN()/1000.-P.y+k[i]*P.x;
	Main();
}


/*
 * Author : Remilia Scarlet
 */

// #pragma comment(linker, "/STACK:102400000,102400000")

#include <bits/stdc++.h>

#define For(i,l,r) for(int _r=r,i=l;i<=_r;++i)
#define rep(i,l,r) for(int _r=r,i=l;i<_r;++i)
#define dto(i,r,l) for(int _l=l,i=r;i>=_l;--i)
#define x first
#define y second
#define pb push_back
#define mk make_pair
#define oo (c=getchar())
#define SZ(V) (int(V.size()))
#define ALL(V) V.begin(),V.end()

using namespace std;

typedef double db;
typedef long long LL;
typedef pair<int ,int> PII;
typedef vector<int> VI;
typedef complex<db> cpx;
typedef vector<PII> VII;
// typedef __int128 bigint;

int ran(){return (rand()<<15)+rand();}

int IN(){
	int x=0;char c;
	for(;oo<48 && c^'-' || c>57;);bool f=c=='-';if(f)oo;
	for(;c>47 && c<58;oo)x=(x<<1)+(x<<3)+c-48;return f?-x:x;
}
void print(int x,char en='\n'){
	printf("%d",x);if(en)putchar(en);
}

void hello(){
	freopen("remi.in","r",stdin);
//	freopen("remi.out","w",stdout);
//	srand(time(0));
}

const db eps = 1e-12;

int dcmp(db x, db y){
	return fabs(x-y)<eps?0:x<y?-1:1;
}

struct ww{
	db x,y;
	db polar(){
		return atan2(y,x);
	}
};

struct fenwick_tree{
	int lim,t[200010];
	void pret(int n){
		For(i,1,lim)t[i] = 0;
		lim = n;
		assert(lim<200010);
	}
	void add(int x, int y){
		assert(x>0);
		for(;x<=lim;x+=x&-x)t[x]+=y;
	}
	int qs(int x){
		if(!x)return 0;
		assert(x>0);
		int an = 0;
		for(;x;x-=x&-x)an+=t[x];
		return an;
	}
}ds;

int n,m;
db k[50010],b[50010],fi[50010];

LL count(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 2*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	ds.pret(c);
	LL res = 0;
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				res += ds.qs(id[k]-1)-ds.qs(fi[li[k].y]);
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				ds.add(id[k],1);
				ds.add(fi[li[k].y],-1);
			}
		}i=j;
	}
	for(auto it:li)fi[it.y] = 0;
	return res;
}

VI seg_list[524289];

db solve(int i,int j){
	if(dcmp(k[i],k[j]) == 0)return 0;
	db x = (b[j]-b[i])/(k[i]-k[j]);
	db y = k[i]*x+b[i];
	return sqrt(x*x+y*y);
}

db sumup(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 2*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	db res = 0;
	int lim = 1;
	for(;lim<c+2;lim<<=1);
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				int line1 = li[k].y;
				for(int u = lim+fi[li[k].y];u;u>>=1)
					for(int line2:seg_list[u]){
						if(n==2000)printf("%d %lf %lf,%d %lf %lf\n",line1,::k[line1],::b[line1],line2,::k[line2],::b[line2]);
						db dis = solve(line1,line2);
						assert(dcmp(dis,R)==-1);
						res += dis;
					}
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				int ll = lim + fi[li[k].y]-1, rr = lim+id[k]+1;
				for(;ll^rr^1;ll>>=1,rr>>=1){
					if(~ll&1)seg_list[ll^1].pb(li[k].y);
					if(rr&1) seg_list[rr^1].pb(li[k].y);
				}
			}
		}i=j;
	}
	return res;
}

void Main(){
	db ll = 0, rr = 3e9;
	rep(tc,0,100){
		db mm = (ll+rr)*.5;
		if(count(mm)<=m)ll = mm;else rr = mm;
	}
	LL cnt = count(ll);
	// if(n==2000)print(cnt),printf("%lf\n",ll);
	assert(cnt<=m && dcmp(ll,rr)==0);
	db ans = sumup(ll);
	ans += (m-cnt)*ll;
	printf("%.20lf\n",ans);
}

int main(int argc, char* argv[]){
	// hello();
	n = IN();
	ww P;
	P.x = IN()/1000., P.y = IN()/1000.;
	m = IN();
	For(i,1,n)k[i] = IN()/1000., b[i] = IN()/1000.-P.y+k[i]*P.x;
/* 	if(n==2000){
		vector<pair<db,PII>> xx;
		For(i,1,n)rep(j,1,i)if(dcmp(k[i],k[j])){
			xx.pb(mk(solve(i,j),PII(i,j)));
		}
		sort(ALL(xx));
		rep(i,0,10)printf("%d %lf %lf %d %lf %lf\n",xx[i].y.x,k[xx[i].y.x],b[xx[i].y.x],xx[i].y.y,k[xx[i].y.y],b[xx[i].y.y]);
	} */
	Main();
}


/*
 * Author : Remilia Scarlet
 */

// #pragma comment(linker, "/STACK:102400000,102400000")

#include <bits/stdc++.h>

#define For(i,l,r) for(int _r=r,i=l;i<=_r;++i)
#define rep(i,l,r) for(int _r=r,i=l;i<_r;++i)
#define dto(i,r,l) for(int _l=l,i=r;i>=_l;--i)
#define x first
#define y second
#define pb push_back
#define mk make_pair
#define oo (c=getchar())
#define SZ(V) (int(V.size()))
#define ALL(V) V.begin(),V.end()

using namespace std;

typedef double db;
typedef long long LL;
typedef pair<int ,int> PII;
typedef vector<int> VI;
typedef complex<db> cpx;
typedef vector<PII> VII;
// typedef __int128 bigint;

int ran(){return (rand()<<15)+rand();}

int IN(){
	int x=0;char c;
	for(;oo<48 && c^'-' || c>57;);bool f=c=='-';if(f)oo;
	for(;c>47 && c<58;oo)x=(x<<1)+(x<<3)+c-48;return f?-x:x;
}
void print(int x,char en='\n'){
	printf("%d",x);if(en)putchar(en);
}

void hello(){
	freopen("remi.in","r",stdin);
//	freopen("remi.out","w",stdout);
//	srand(time(0));
}

const db eps = 1e-12;

int dcmp(db x, db y){
	return fabs(x-y)<eps?0:x<y?-1:1;
}

struct ww{
	db x,y;
	db polar(){
		return atan2(y,x);
	}
};

struct fenwick_tree{
	int lim,t[200010];
	void pret(int n){
		For(i,1,lim)t[i] = 0;
		lim = n;
		assert(lim<200010);
	}
	void add(int x, int y){
		assert(x>0);
		for(;x<=lim;x+=x&-x)t[x]+=y;
	}
	int qs(int x){
		if(!x)return 0;
		assert(x>0);
		int an = 0;
		for(;x;x-=x&-x)an+=t[x];
		return an;
	}
}ds;

int n,m;
db k[50010],b[50010],fi[50010];

LL count(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 2*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	ds.pret(c);
	LL res = 0;
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				res += ds.qs(id[k]-1)-ds.qs(fi[li[k].y]);
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				ds.add(id[k],1);
				ds.add(fi[li[k].y],-1);
			}
		}i=j;
	}
	for(auto it:li)fi[it.y] = 0;
	return res;
}

VI seg_list[524289];

db solve(int i,int j){
	if(dcmp(k[i],k[j]) == 0)return 0;
	db x = (b[j]-b[i])/(k[i]-k[j]);
	db y = k[i]*x+b[i];
	return sqrt(x*x+y*y);
}

db sumup(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 2*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	db res = 0;
	int lim = 1;
	for(;lim<c+2;lim<<=1);
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				int line1 = li[k].y;
				for(int u = lim+fi[li[k].y];u;u>>=1)
					for(int line2:seg_list[u]){
						if(n==2000)print(line1,' '),print(line2,' ');
						db dis = solve(line1,line2);
						assert(dcmp(dis,R)==-1);
						res += dis;
					}
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				int ll = lim + fi[li[k].y]-1, rr = lim+id[k]+1;
				for(;ll^rr^1;ll>>=1,rr>>=1){
					if(~ll&1)seg_list[ll^1].pb(li[k].y);
					if(rr&1) seg_list[rr^1].pb(li[k].y);
				}
			}
		}i=j;
	}
	return res;
}

void Main(){
	db ll = 0, rr = 3e9;
	rep(tc,0,100){
		db mm = (ll+rr)*.5;
		if(count(mm)<=m)ll = mm;else rr = mm;
	}
	LL cnt = count(ll);
	// if(n==2000)print(cnt),printf("%lf\n",ll);
	assert(cnt<=m && dcmp(ll,rr)==0);
	db ans = sumup(ll);
	ans += (m-cnt)*ll;
	printf("%.20lf\n",ans);
}

int main(int argc, char* argv[]){
	// hello();
	n = IN();
	ww P;
	P.x = IN()/1000., P.y = IN()/1000.;
	m = IN();
	For(i,1,n)k[i] = IN()/1000., b[i] = IN()/1000.-P.y+k[i]*P.x;
	Main();
}


/*
 * Author : Remilia Scarlet
 */

// #pragma comment(linker, "/STACK:102400000,102400000")

#include <bits/stdc++.h>

#define For(i,l,r) for(int _r=r,i=l;i<=_r;++i)
#define rep(i,l,r) for(int _r=r,i=l;i<_r;++i)
#define dto(i,r,l) for(int _l=l,i=r;i>=_l;--i)
#define x first
#define y second
#define pb push_back
#define mk make_pair
#define oo (c=getchar())
#define SZ(V) (int(V.size()))
#define ALL(V) V.begin(),V.end()

using namespace std;

typedef double db;
typedef long long LL;
typedef pair<int ,int> PII;
typedef vector<int> VI;
typedef complex<db> cpx;
typedef vector<PII> VII;
// typedef __int128 bigint;

int ran(){return (rand()<<15)+rand();}

int IN(){
	int x=0;char c;
	for(;oo<48 && c^'-' || c>57;);bool f=c=='-';if(f)oo;
	for(;c>47 && c<58;oo)x=(x<<1)+(x<<3)+c-48;return f?-x:x;
}
void print(int x,char en='\n'){
	printf("%d",x);if(en)putchar(en);
}

void hello(){
	freopen("remi.in","r",stdin);
//	freopen("remi.out","w",stdout);
//	srand(time(0));
}

const db eps = 1e-16;

int dcmp(db x, db y){
	return fabs(x-y)<eps?0:x<y?-1:1;
}

struct ww{
	db x,y;
	db polar(){
		return atan2(y,x);
	}
};

struct fenwick_tree{
	int lim,t[200010];
	void pret(int n){
		For(i,1,lim)t[i] = 0;
		lim = n;
		assert(lim<200010);
	}
	void add(int x, int y){
		assert(x>0);
		for(;x<=lim;x+=x&-x)t[x]+=y;
	}
	int qs(int x){
		if(!x)return 0;
		assert(x>0);
		int an = 0;
		for(;x;x-=x&-x)an+=t[x];
		return an;
	}
}ds;

int n,m;
db k[50010],b[50010],fi[50010];

LL count(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 4*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	ds.pret(c);
	LL res = 0;
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				res += ds.qs(id[k]-1)-ds.qs(fi[li[k].y]);
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				ds.add(id[k],1);
				ds.add(fi[li[k].y],-1);
			}
		}i=j;
	}
	for(auto it:li)fi[it.y] = 0;
	return res;
}

VI seg_list[524289];

db solve(int i,int j){
	assert(dcmp(k[i],k[j]));
	if(dcmp(k[i],k[j]) == 0)return 0;
	db x = (b[j]-b[i])/(k[i]-k[j]);
	db y = k[i]*x+b[i];
	return sqrt(x*x+y*y);
}

auto sumup(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 4*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	db res = 0;
	int cnt = 0;
	int lim = 1;
	for(;lim<c+2;lim<<=1);
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				int line1 = li[k].y;
				for(int u = lim+fi[li[k].y];u;u>>=1)
					for(int line2:seg_list[u]){
						db dis = solve(line1,line2);
						res += dis;
						++cnt;
					}
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				int ll = lim + fi[li[k].y], rr = lim+id[k];
				for(;ll^rr^1;ll>>=1,rr>>=1){
					if(~ll&1)seg_list[ll^1].pb(li[k].y);
					if(rr&1) seg_list[rr^1].pb(li[k].y);
				}
			}
		}i=j;
	}
	return mk(res,cnt);
}

void Main(){
	db ll = 0, rr = 3e9;
	rep(tc,0,100){
		db mm = (ll+rr)*.5;
		if(count(mm)<=m)ll = mm;else rr = mm;
	}
	auto it = sumup(ll);
	assert(it.y<=m);
	printf("%.20lf\n",it.x+(m-it.y)*ll);
}

int main(int argc, char* argv[]){
	// hello();
	n = IN();
	ww P;
	P.x = IN()/1000., P.y = IN()/1000.;
	m = IN();
	For(i,1,n)k[i] = IN()/1000., b[i] = IN()/1000.-P.y+k[i]*P.x;
	Main();
}


/*
 * Author : Remilia Scarlet
 */

// #pragma comment(linker, "/STACK:102400000,102400000")

#include <bits/stdc++.h>

#define For(i,l,r) for(int _r=r,i=l;i<=_r;++i)
#define rep(i,l,r) for(int _r=r,i=l;i<_r;++i)
#define dto(i,r,l) for(int _l=l,i=r;i>=_l;--i)
#define x first
#define y second
#define pb push_back
#define mk make_pair
#define oo (c=getchar())
#define SZ(V) (int(V.size()))
#define ALL(V) V.begin(),V.end()

using namespace std;

typedef double db;
typedef long long LL;
typedef pair<int ,int> PII;
typedef vector<int> VI;
typedef complex<db> cpx;
typedef vector<PII> VII;
// typedef __int128 bigint;

int ran(){return (rand()<<15)+rand();}

int IN(){
	int x=0;char c;
	for(;oo<48 && c^'-' || c>57;);bool f=c=='-';if(f)oo;
	for(;c>47 && c<58;oo)x=(x<<1)+(x<<3)+c-48;return f?-x:x;
}
void print(int x,char en='\n'){
	printf("%d",x);if(en)putchar(en);
}

void hello(){
	freopen("remi.in","r",stdin);
//	freopen("remi.out","w",stdout);
//	srand(time(0));
}

const db eps = 1e-12;

int dcmp(db x, db y){
	return fabs(x-y)<eps?0:x<y?-1:1;
}

struct ww{
	db x,y;
	db polar(){
		return atan2(y,x);
	}
};

struct fenwick_tree{
	int lim,t[200010];
	void pret(int n){
		For(i,1,lim)t[i] = 0;
		lim = n;
		assert(lim<200010);
	}
	void add(int x, int y){
		assert(x>0);
		for(;x<=lim;x+=x&-x)t[x]+=y;
	}
	int qs(int x){
		if(!x)return 0;
		assert(x>0);
		int an = 0;
		for(;x;x-=x&-x)an+=t[x];
		return an;
	}
}ds;

int n,m;
db k[50010],b[50010],fi[50010];

LL count(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 2*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	ds.pret(c);
	LL res = 0;
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				res += ds.qs(id[k]-1)-ds.qs(fi[li[k].y]);
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				ds.add(id[k],1);
				ds.add(fi[li[k].y],-1);
			}
		}i=j;
	}
	for(auto it:li)fi[it.y] = 0;
	return res;
}

VI seg_list[524289];

db solve(int i,int j){
	if(dcmp(k[i],k[j]) == 0)return 0;
	db x = (b[j]-b[i])/(k[i]-k[j]);
	db y = k[i]*x+b[i];
	return sqrt(x*x+y*y);
}

db sumup(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 2*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	db res = 0;
	int lim = 1;
	for(;lim<c+2;lim<<=1);
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				int line1 = li[k].y;
				for(int u = lim+fi[li[k].y];u;u>>=1)
					for(int line2:seg_list[u]){
						if(n==2000)printf("%d %lf %lf,%d %lf %lf\n",line1,::k[line1],::b[line1],line2,::k[line2],::b[line2]);
						db dis = solve(line1,line2);
						assert(dcmp(dis,R)==-1);
						res += dis;
					}
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				int ll = lim + fi[li[k].y]-1, rr = lim+id[k]+1;
				for(;ll^rr^1;ll>>=1,rr>>=1){
					if(~ll&1)seg_list[ll^1].pb(li[k].y);
					if(rr&1) seg_list[rr^1].pb(li[k].y);
				}
			}
		}i=j;
	}
	return res;
}

void Main(){
	db ll = 0, rr = 3e9;
	rep(tc,0,100){
		db mm = (ll+rr)*.5;
		if(count(mm)<=m)ll = mm;else rr = mm;
	}
	LL cnt = count(ll);
	// if(n==2000)print(cnt),printf("%lf\n",ll);
	assert(cnt<=m && dcmp(ll,rr)==0);
	db ans = sumup(ll);
	ans += (m-cnt)*ll;
	printf("%.20lf\n",ans);
}

int main(int argc, char* argv[]){
	// hello();
	n = IN();
	ww P;
	P.x = IN()/1000., P.y = IN()/1000.;
	m = IN();
	For(i,1,n)k[i] = IN()/1000., b[i] = IN()/1000.-P.y+k[i]*P.x;
	if(n==2000){
		vector<pair<db,PII>> xx;
		For(i,1,n)rep(j,1,i)if(dcmp(k[i],k[j])){
			xx.pb(mk(solve(i,j),PII(i,j)));
		}
		sort(ALL(xx));
		rep(i,0,10)printf("%d %lf %lf %d %lf %lf\n",xx[i].y.x,k[xx[i].y.x],b[xx[i].y.x],xx[i].y.y,k[xx[i].y.y],b[xx[i].y.y]);
	}
	Main();
}


/*
 * Author : Remilia Scarlet
 */

// #pragma comment(linker, "/STACK:102400000,102400000")

#include <bits/stdc++.h>

#define For(i,l,r) for(int _r=r,i=l;i<=_r;++i)
#define rep(i,l,r) for(int _r=r,i=l;i<_r;++i)
#define dto(i,r,l) for(int _l=l,i=r;i>=_l;--i)
#define x first
#define y second
#define pb push_back
#define mk make_pair
#define oo (c=getchar())
#define SZ(V) (int(V.size()))
#define ALL(V) V.begin(),V.end()

using namespace std;

typedef double db;
typedef long long LL;
typedef pair<int ,int> PII;
typedef vector<int> VI;
typedef complex<db> cpx;
typedef vector<PII> VII;
// typedef __int128 bigint;

int ran(){return (rand()<<15)+rand();}

int IN(){
	int x=0;char c;
	for(;oo<48 && c^'-' || c>57;);bool f=c=='-';if(f)oo;
	for(;c>47 && c<58;oo)x=(x<<1)+(x<<3)+c-48;return f?-x:x;
}
void print(int x,char en='\n'){
	printf("%d",x);if(en)putchar(en);
}

void hello(){
	freopen("remi.in","r",stdin);
//	freopen("remi.out","w",stdout);
//	srand(time(0));
}

const db eps = 1e-12;

int dcmp(db x, db y){
	return fabs(x-y)<eps?0:x<y?-1:1;
}

struct ww{
	db x,y;
	db polar(){
		return atan2(y,x);
	}
};

struct fenwick_tree{
	int lim,t[200010];
	void pret(int n){
		For(i,1,lim)t[i] = 0;
		lim = n;
		assert(lim<200010);
	}
	void add(int x, int y){
		assert(x>0);
		for(;x<=lim;x+=x&-x)t[x]+=y;
	}
	int qs(int x){
		if(!x)return 0;
		assert(x>0);
		int an = 0;
		for(;x;x-=x&-x)an+=t[x];
		return an;
	}
}ds;

int n,m;
db k[50010],b[50010],fi[50010];

LL count(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 2*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	ds.pret(c);
	LL res = 0;
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				res += ds.qs(id[k]-1)-ds.qs(fi[li[k].y]);
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				ds.add(id[k],1);
				ds.add(fi[li[k].y],-1);
			}
		}i=j;
	}
	for(auto it:li)fi[it.y] = 0;
	return res;
}

VI seg_list[524289];

db solve(int i,int j){
	if(dcmp(k[i],k[j]) == 0)return 0;
	db x = (b[j]-b[i])/(k[i]-k[j]);
	db y = k[i]*x+b[i];
	return sqrt(x*x+y*y);
}

db sumup(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 2*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	db res = 0;
	int lim = 1;
	for(;lim<c+2;lim<<=1);
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				int line1 = li[k].y;
				for(int u = lim+fi[li[k].y];u;u>>=1)
					for(int line2:seg_list[u]){
						db dis = solve(line1,line2);
						assert(dcmp(dis,R)==-1);
						res += dis;
					}
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				int ll = lim + fi[li[k].y]-1, rr = lim+id[k]+1;
				for(;ll^rr^1;ll>>=1,rr>>=1){
					if(~ll&1)seg_list[ll^1].pb(li[k].y);
					if(rr&1) seg_list[rr^1].pb(li[k].y);
				}
			}
		}i=j;
	}
	return res;
}

void Main(){
	db ll = 0, rr = 3e9;
	rep(tc,0,100){
		db mm = (ll+rr)*.5;
		if(count(mm)<=m)ll = mm;else rr = mm;
	}
	LL cnt = count(ll);
	cerr<<cnt<<endl;
	assert(cnt<=m && dcmp(ll,rr)==0);
	db ans = sumup(ll);
	ans += (m-cnt)*ll;
	printf("%.20lf\n",ans);
}

int main(int argc, char* argv[]){
	// hello();
	n = IN();
	ww P;
	P.x = IN()/1000., P.y = IN()/1000.;
	m = IN();
	For(i,1,n)k[i] = IN()/1000., b[i] = IN()/1000.-P.y+k[i]*P.x;
	Main();
}


/*
 * Author : Remilia Scarlet
 */

// #pragma comment(linker, "/STACK:102400000,102400000")

#include <bits/stdc++.h>

#define For(i,l,r) for(int _r=r,i=l;i<=_r;++i)
#define rep(i,l,r) for(int _r=r,i=l;i<_r;++i)
#define dto(i,r,l) for(int _l=l,i=r;i>=_l;--i)
#define x first
#define y second
#define pb push_back
#define mk make_pair
#define oo (c=getchar())
#define SZ(V) (int(V.size()))
#define ALL(V) V.begin(),V.end()

using namespace std;

typedef double db;
typedef long long LL;
typedef pair<int ,int> PII;
typedef vector<int> VI;
typedef complex<db> cpx;
typedef vector<PII> VII;
// typedef __int128 bigint;

int ran(){return (rand()<<15)+rand();}

int IN(){
	int x=0;char c;
	for(;oo<48 && c^'-' || c>57;);bool f=c=='-';if(f)oo;
	for(;c>47 && c<58;oo)x=(x<<1)+(x<<3)+c-48;return f?-x:x;
}
void print(int x,char en='\n'){
	printf("%d",x);if(en)putchar(en);
}

void hello(){
	freopen("remi.in","r",stdin);
//	freopen("remi.out","w",stdout);
//	srand(time(0));
}

const db eps = 1e-12;

int dcmp(db x, db y){
	return fabs(x-y)<eps?0:x<y?-1:1;
}

struct ww{
	db x,y;
	db polar(){
		return atan2(y,x);
	}
};

struct fenwick_tree{
	int lim,t[200010];
	void pret(int n){
		For(i,1,lim)t[i] = 0;
		lim = n;
		assert(lim<200010);
	}
	void add(int x, int y){
		assert(x>0);
		for(;x<=lim;x+=x&-x)t[x]+=y;
	}
	int qs(int x){
		if(!x)return 0;
		assert(x>0);
		int an = 0;
		for(;x;x-=x&-x)an+=t[x];
		return an;
	}
}ds;

int n,m;
db k[50010],b[50010],fi[50010];

LL count(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 4*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	ds.pret(c);
	LL res = 0;
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				res += ds.qs(id[k]-1)-ds.qs(fi[li[k].y]);
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				ds.add(id[k],1);
				ds.add(fi[li[k].y],-1);
			}
		}i=j;
	}
	for(auto it:li)fi[it.y] = 0;
	return res;
}

VI seg_list[524289];

db solve(int i,int j){
	if(dcmp(k[i],k[j]) == 0)return 0;
	db x = (b[j]-b[i])/(k[i]-k[j]);
	db y = k[i]*x+b[i];
	return sqrt(x*x+y*y);
}

db sumup(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 4*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	db res = 0;
	int lim = 1;
	for(;lim<c+2;lim<<=1);
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				int line1 = li[k].y;
				for(int u = lim+fi[li[k].y];u;u>>=1)
					for(int line2:seg_list[u]){
						db dis = solve(line1,line2);
						assert(dcmp(dis,R)==-1);
						res += dis;
					}
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				int ll = lim + fi[li[k].y]-1, rr = lim+id[k]+1;
				for(;ll^rr^1;ll>>=1,rr>>=1){
					if(~ll&1)seg_list[ll^1].pb(li[k].y);
					if(rr&1) seg_list[rr^1].pb(li[k].y);
				}
			}
		}i=j;
	}
	return res;
}

void Main(){
	db ll = 0, rr = 3e9;
	rep(tc,0,80){
		db mm = (ll+rr)*.5;
		if(count(mm)<=m)ll = mm;else rr = mm;
	}
	LL cnt = count(ll);
	assert(cnt<=m);
	db ans = sumup(ll);
	ans += (m-cnt)*ll;
	printf("%.20lf\n",ans);
}

int main(int argc, char* argv[]){
	// hello();
	n = IN();
	ww P;
	P.x = IN()/1000., P.y = IN()/1000.;
	m = IN();
	For(i,1,n)k[i] = IN()/1000., b[i] = IN()/1000.-P.y+k[i]*P.x;
	Main();
}


/*
 * Author : Remilia Scarlet
 */

// #pragma comment(linker, "/STACK:102400000,102400000")

#include <bits/stdc++.h>

#define For(i,l,r) for(int _r=r,i=l;i<=_r;++i)
#define rep(i,l,r) for(int _r=r,i=l;i<_r;++i)
#define dto(i,r,l) for(int _l=l,i=r;i>=_l;--i)
#define x first
#define y second
#define pb push_back
#define mk make_pair
#define oo (c=getchar())
#define SZ(V) (int(V.size()))
#define ALL(V) V.begin(),V.end()

using namespace std;

typedef double db;
typedef long long LL;
typedef pair<int ,int> PII;
typedef vector<int> VI;
typedef complex<db> cpx;
typedef vector<PII> VII;
// typedef __int128 bigint;

int ran(){return (rand()<<15)+rand();}

int IN(){
	int x=0;char c;
	for(;oo<48 && c^'-' || c>57;);bool f=c=='-';if(f)oo;
	for(;c>47 && c<58;oo)x=(x<<1)+(x<<3)+c-48;return f?-x:x;
}
void print(int x,char en='\n'){
	printf("%d",x);if(en)putchar(en);
}

void hello(){
	freopen("remi.in","r",stdin);
//	freopen("remi.out","w",stdout);
//	srand(time(0));
}

const db eps = 1e-12;

int dcmp(db x, db y){
	return fabs(x-y)<eps?0:x<y?-1:1;
}

struct ww{
	db x,y;
	db polar(){
		return atan2(y,x);
	}
/* 	bool operator == (const ww&A){
		return dcmp(x,A.x)==0 && dcmp(y,A.y)==0;
	} */
};

struct fenwick_tree{
	int lim,t[200010];
	void pret(int n){
		For(i,1,lim)t[i] = 0;
		lim = n;
	}
	void add(int x, int y){
		assert(x>0);
		for(;x<=lim;x+=x&-x)t[x]+=y;
	}
	int qs(int x){
		if(!x)return 0;
		assert(x>0);
		int an = 0;
		for(;x;x-=x&-x)an+=t[x];
		return an;
	}
}ds;

int n,m;
db k[50010],b[50010],fi[50010];

LL count(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 2*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	ds.pret(c);
	LL res = 0;
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				res += ds.qs(id[k]-1)-ds.qs(fi[li[k].y]);
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				ds.add(id[k],1);
				ds.add(fi[li[k].y],-1);
			}
		}i=j;
	}
	for(auto it:li)fi[it.y] = 0;
	return res;
}

VI seg_list[524289];

db solve(int i,int j){
	if(dcmp(k[i],k[j]) == 0)return 0;
	db x = (b[j]-b[i])/(k[i]-k[j]);
	db y = k[i]*x+b[i];
	return sqrt(x*x+y*y);
}

db sumup(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 2*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	db res = 0;
	int lim = 1;
	for(;lim<c+2;lim<<=1);
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				int line1 = li[k].y;
				for(int u = lim+fi[li[k].y];u;u>>=1)
					for(int line2:seg_list[u]){
						db dis = solve(line1,line2);
						assert(dcmp(dis,R)==-1);
						res += dis;
					}
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				int ll = lim + fi[li[k].y]-1, rr = lim+id[k]+1;
				for(;ll^rr^1;ll>>=1,rr>>=1){
					if(~ll&1)seg_list[ll^1].pb(li[k].y);
					if(rr&1) seg_list[rr^1].pb(li[k].y);
				}
			}
		}i=j;
	}
	return res;
}

void Main(){
	db ll = 0, rr = 3e9;
	rep(tc,0,80){
		db mm = (ll+rr)*.5;
		if(count(mm)<=m)ll = mm;else rr = mm;
	}
	LL cnt = count(ll);
	assert(cnt<=m);
	db ans = sumup(ll);
	ans += (m-cnt)*ll;
	printf("%.20lf\n",ans);
}

int main(int argc, char* argv[]){
	// hello();
	n = IN();
	ww P;
	P.x = IN()/1000., P.y = IN()/1000.;
	m = IN();
	For(i,1,n)k[i] = IN()/1000., b[i] = IN()/1000.-P.y+k[i]*P.x;
	Main();
}


#include <bits/stdc++.h>

using namespace std;

using ld = double;

const ld pi = acos(-1);

struct fenwick {
  vector<int> fenw;
  int n;

  fenwick(int n) : n(n) {
    fenw.resize(n);
  }

  void modify(int x, int v) {
    while (x < n) {
      fenw[x] += v;
      x |= x + 1;
    }
  }

  int query(int x) {
    int res = 0;
    while (x >= 0) {
      res += fenw[x];
      x = (x & (x + 1)) - 1;
    }
    return res;
  }
};

ld norm(ld x) {
  while (x < 0) {
    x += pi * 2;
  }
  while (x >= pi * 2) {
    x -= pi * 2;
  }
  return x;
}

int main() {
#ifdef LOCAL
  freopen("input.txt", "r", stdin);
#endif
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  ld x, y;
  cin >> n >> x >> y >> m;
  x /= 1000; y /= 1000;
  vector<ld> a(n), b(n), angle(n);
  for (int i = 0; i < n; ++i) {
    cin >> a[i] >> b[i];
    a[i] /= 1000; b[i] /= 1000;
    angle[i] = atan(a[i]);
    if (y > a[i] * x + b[i]) {
      angle[i] -= pi / 2;
    } else {
      angle[i] += pi / 2;
    }
  }
  ld low = 0, high = 2e9;
  for (int rep = 0; rep < 60; ++rep) {
    ld r = (low + high) / 2;
    vector<pair<ld, ld>> p;
    for (int i = 0; i < n; ++i) {
      ld d = abs((a[i] * x - y + b[i]) / (sqrt(a[i] * a[i] + 1)));
      if (d < r) {
        ld delta = acos(d / r);
        p.emplace_back(norm(angle[i] - delta), norm(angle[i] + delta));
        if (p.back().first > p.back().second) {
          swap(p.back().first, p.back().second);
        }
      }
    }
    int s = p.size();
    sort(p.begin(), p.end());
    vector<ld> d(s);
    for (int i = 0; i < s; ++i) {
      d[i] = p[i].second;
    }
    sort(d.begin(), d.end());
    fenwick fenw(s);
    long long cnt = 0;
    for (int i = 0; i < s; ++i) {
      int l = lower_bound(d.begin(), d.end(), p[i].first) - d.begin();
      int r = lower_bound(d.begin(), d.end(), p[i].second) - d.begin();
      cnt += fenw.query(r) - fenw.query(l - 1);
      fenw.modify(r, 1);
    }
    if (cnt <= m) {
      low = r;
    } else {
      high = r;
    }
  }
  ld r = low;
  vector<pair<pair<ld, ld>, int>> p;
  for (int i = 0; i < n; ++i) {
    ld d = abs((a[i] * x - y + b[i]) / (sqrt(a[i] * a[i] + 1)));
    if (d < r) {
      ld delta = acos(d / r);
      p.emplace_back(make_pair(norm(angle[i] - delta), norm(angle[i] + delta)), i);
      if (p.back().first.first > p.back().first.second) {
        swap(p.back().first.first, p.back().first.second);
      }
    }
  }
  int s = p.size(), take = 0;
  sort(p.begin(), p.end());
  set<pair<ld, int>> st;
  ld ans = 0;
  for (int i = 0; i < s; ++i) {
    auto it = st.lower_bound(make_pair(p[i].first.first, -1));
    while (it != st.end()) {
      if (it->first > p[i].first.second) {
        break;
      }
      int j = it->second;
      int k = p[i].second;
      ld xx = (b[k] - b[j]) / (a[j] - a[k]);
      ld yy = a[j] * xx + b[j];
      ans += sqrt((x - xx) * (x - xx) + (y - yy) * (y - yy));
      ++take;
      ++it;
    }
    st.emplace(p[i].first.second, p[i].second);
  }
  cout << fixed << setprecision(10) << ans + (m - take) * low << "\n";
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

using ld = double;

const ld pi = acos(-1);

struct fenwick {
  vector<int> fenw;
  int n;

  fenwick(int n) : n(n) {
    fenw.resize(n);
  }

  void modify(int x, int v) {
    while (x < n) {
      fenw[x] += v;
      x |= x + 1;
    }
  }

  int query(int x) {
    int res = 0;
    while (x >= 0) {
      res += fenw[x];
      x = (x & (x + 1)) - 1;
    }
    return res;
  }
};

ld norm(ld x) {
  while (x < 0) {
    x += pi * 2;
  }
  while (x >= pi * 2) {
    x -= pi * 2;
  }
  return x;
}

int main() {
#ifdef LOCAL
  freopen("input.txt", "r", stdin);
#endif
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  ld x, y;
  cin >> n >> x >> y >> m;
  x /= 1000; y /= 1000;
  vector<ld> a(n), b(n), angle(n);
  for (int i = 0; i < n; ++i) {
    cin >> a[i] >> b[i];
    a[i] /= 1000; b[i] /= 1000;
    angle[i] = atan(a[i]);
    if (y > a[i] * x + b[i]) {
      angle[i] -= pi / 2;
    } else {
      angle[i] += pi / 2;
    }
  }
  ld low = 0, high = 2e9;
  for (int rep = 0; rep < 60; ++rep) {
    ld r = (low + high) / 2;
    vector<pair<ld, ld>> p;
    for (int i = 0; i < n; ++i) {
      ld d = abs((a[i] * x - y + b[i]) / (sqrt(a[i] * a[i]) + 1));
      if (d < r) {
        ld delta = acos(d / r);
        p.emplace_back(norm(angle[i] - delta), norm(angle[i] + delta));
        if (p.back().first > p.back().second) {
          swap(p.back().first, p.back().second);
        }
      }
    }
    int s = p.size();
    sort(p.begin(), p.end());
    vector<ld> d(s);
    for (int i = 0; i < s; ++i) {
      d[i] = p[i].second;
    }
    sort(d.begin(), d.end());
    fenwick fenw(s);
    long long cnt = 0;
    for (int i = 0; i < s; ++i) {
      int l = lower_bound(d.begin(), d.end(), p[i].first) - d.begin();
      int r = lower_bound(d.begin(), d.end(), p[i].second) - d.begin();
      cnt += fenw.query(r) - fenw.query(l - 1);
      fenw.modify(r, 1);
    }
    if (cnt <= m) {
      low = r;
    } else {
      high = r;
    }
  }
  ld r = low;
  vector<pair<pair<ld, ld>, int>> p;
  for (int i = 0; i < n; ++i) {
    ld d = abs((a[i] * x - y + b[i]) / (sqrt(a[i] * a[i]) + 1));
    if (d < r) {
      ld delta = acos(d / r);
      p.emplace_back(make_pair(norm(angle[i] - delta), norm(angle[i] + delta)), i);
      if (p.back().first.first > p.back().first.second) {
        swap(p.back().first.first, p.back().first.second);
      }
    }
  }
  int s = p.size(), take = 0;
  sort(p.begin(), p.end());
  set<pair<ld, int>> st;
  ld ans = 0;
  for (int i = 0; i < s; ++i) {
    auto it = st.lower_bound(make_pair(p[i].first.first, -1));
    while (it != st.end()) {
      if (it->first > p[i].first.second) {
        break;
      }
      int j = it->second;
      int k = p[i].second;
      ld xx = (b[k] - b[j]) / (a[j] - a[k]);
      ld yy = a[j] * xx + b[j];
      ans += sqrt((x - xx) * (x - xx) + (y - yy) * (y - yy));
      ++take;
      ++it;
    }
    st.emplace(p[i].first.second, p[i].second);
  }
  cout << fixed << setprecision(10) << ans + (m - take) * low << "\n";
  return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <set>

#define FILL(a, n, x) memset((a), (x), sizeof ((a)[0]) * (n))
#define COPY(a, n, b) memcpy((b), (a), sizeof ((a)[0]) * (n))
#define FILLA(a, x) memset((a), (x), sizeof (a))
#define COPYA(a, b) memcpy((b), (a), sizeof (a))

using namespace std;

typedef long long li;
typedef unsigned long long lu;
const li infl = ~0LLU >> 2;

template <class T>
inline void Min(T &x, T y) {
  if (y < x) x = y;
}
template <class T>
inline void Max(T &x, T y) {
  if (y > x) x = y;
}

/*

const int mod = 998244353;
inline int Add(int x) { return x >= mod ? x - mod : x; }
inline void Add(int &x, int y) { x += y; if (x >= mod) x -= mod; }
inline int Sub(int x) { return x < 0 ? x + mod : x; }
inline void Sub(int &x, int y) { x -= y; if (x < 0) x += mod; }
inline int Mul(int x, int y) { return (int)((li)x * y % mod); }
inline int Mul(int x, int y, int z) { return Mul(x, Mul(y, z)); }
int Pow(int x, int y) {
  int z = 1;
  for (; y; y >>= 1) {
    if (y & 1) z = Mul(z, x);
    x = Mul(x, x);
  }
  return z;
}
int Inv(int x) {
  return Pow(x, mod - 2);
}

*/

// ----------------------------------------

typedef long double real;

const int maxn = 50000;
const real scale = 1e3, pi = acos(-1.0L), eps = 1e-12L;

int n, m, ns;
real cx, cy;
real la[maxn], lb[maxn];

pair<real, real> seg[maxn];
real arcs[maxn * 2];

struct Seg {
  int l, r, id;
  bool operator < (const Seg &b) const {
    return l < b.l || (l == b.l && r < b.r);
  }
} segi[maxn];

int ord[maxn];

real Fix(real x) {
  while (x >= pi) x -= 2 * pi;
  while (x < -pi) x += 2 * pi;
  return x;
}

void MakeSegments(real radius) {
  ns = 0;

  for (int i = 0; i < n; ++i) {
    real down = sqrt(la[i] * la[i] + 1);
    real up = cy - la[i] * cx - lb[i];
    real dist = up / down;  // negative if below, positive if above
    if (dist > radius) continue;

    real alpha = atan2(la[i], 1) - pi / 2;
    if (dist < 0) {
      dist *= -1;
      alpha += pi;
    }

    real len_sqr = radius * radius - dist * dist;
    real delta = acos((radius * radius + dist * dist - len_sqr) /
                      (2 * radius * dist));
    if (dist < eps) delta = pi / 2;
    real beta1 = Fix(alpha + delta), beta2 = Fix(alpha - delta);
    if (beta1 > beta2) swap(beta1, beta2);
    seg[ns] = {beta1, beta2};

    arcs[2 * ns] = beta1;
    arcs[2 * ns + 1] = beta2;

    ++ns;
  }

  sort(arcs, arcs + 2 * ns);

  for (int i = 0; i < ns; ++i) {
    segi[i].l = (int)(lower_bound(arcs, arcs + 2 * ns, seg[i].first) - arcs);
    segi[i].r = (int)(lower_bound(arcs, arcs + 2 * ns + 1, seg[i].second) -
                      arcs);
    segi[i].id = i;
  }
  sort(segi, segi + ns);

  for (int i = 0; i < ns; ++i) {
    ord[i] = i;
  }
  sort(ord, ord + ns, [](int i, int j) { return segi[i].r < segi[j].r; });
}

namespace bit {
  int N;
  int bit[2 * maxn];

  void Init(void) {
    N = 2 * ns;
    FILL(bit, N, 0);
  }

  int Low(int i) {
    return i & -i;
  }

  void Add(int i, int x) {
    for (; i < N; i += Low(i + 1)) {
      bit[i] += x;
    }
  }

  int Sum(int i) {
    int sum = 0;
    for (; i >= 0; i -= Low(i + 1)) {
      sum += bit[i];
    }
    return sum;
  }
}

li Count(real radius) {
  MakeSegments(radius);

  // printf("-------------------- Start Count %lf --------------------\n", radius);
  // for (int i = 0; i < ns; ++i) {
  //   printf("seg %lf %lf\n", seg[i].first / pi, seg[i].second / pi);
  // }
  // for (int i = 0; i < ns; ++i) {
  //   printf("segi %d %d %d\n", segi[i].l, segi[i].r, i);
  // }

  bit::Init();
  using bit::Add;
  using bit::Sum;

  li ans = 0;
  int next = 0;
  for (int i = 0; i < ns; ++i) {
    int l = segi[i].l, r = segi[i].r;
    while (next < ns && segi[ord[next]].r < l) {
      Add(segi[ord[next]].r, -1);
      ++next;
    }
    ans += Sum(r);
    Add(r, 1);
  }

  // printf("Count(%lf) = %lld\n", radius, ans);

  return ans;
}

struct Cmp {
  bool operator () (const Seg &a, const Seg &b) const {
    if (a.r != b.r) return a.r < b.r;
    return a.id < b.id;
  }
};

void Get(int id, real &k, real &b) {
  k = la[id];
  b = lb[id];
}

real Cost(int id1, int id2) {
  real k1, b1, k2, b2;
  Get(id1, k1, b1);
  Get(id2, k2, b2);
  real x = (b2 - b1) / (k1 - k2);
  real y = k1 * x + b1;
  x -= cx;
  y -= cy;
  // printf("cost(%d, %d): (%lf, %lf)\n", id1, id2, x, y);
  return sqrt(x * x + y * y);
}

pair<li, real> Output(real radius) {
  MakeSegments(radius);

  set<Seg, Cmp> s;
  typedef set<Seg, Cmp>::iterator Iter;

  li cnt = 0;
  int next = 0;
  real sum = 0;
  for (int i = 0; i < ns; ++i) {
    int l = segi[i].l, r = segi[i].r;
    while (next < ns && segi[ord[next]].r < l) {
      s.erase(segi[ord[next]]);
      ++next;
    }
    for (Iter x = s.begin(); x != s.end(); ++x) {
      if (x->r > r) break;
      ++cnt;
      sum += Cost(x->id, segi[i].id);
    }
    s.insert(segi[i]);
  }

  return {cnt, sum};
}

real Solve(void) {
  real low = 0, high = 1e12;
  for (int i = 0; i < 100; ++i) {
    real mid = (low + high) * 0.5;
    if (Count(mid) > m) {
      high = mid;
    } else {
      low = mid;
    }
  }
  // printf("low = %lf\n", low);
  real radius = low;
  pair<li, real> res = Output(radius);
  return res.second + (real)(m - res.first) * radius;
}

int main(void) {
  scanf("%d", &n);
  int x, y;
  scanf("%d%d%d", &x, &y, &m);
  cx = x / scale;
  cy = y / scale;

  for (int i = 0; i < n; ++i) {
    scanf("%d%d", &x, &y);
    la[i] = x / scale;
    lb[i] = y / scale;
  }
  real ans = Solve();
  printf("%.20Lf\n", ans);
  return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <set>

#define FILL(a, n, x) memset((a), (x), sizeof ((a)[0]) * (n))
#define COPY(a, n, b) memcpy((b), (a), sizeof ((a)[0]) * (n))
#define FILLA(a, x) memset((a), (x), sizeof (a))
#define COPYA(a, b) memcpy((b), (a), sizeof (a))

using namespace std;

typedef long long li;
typedef unsigned long long lu;
const li infl = ~0LLU >> 2;

template <class T>
inline void Min(T &x, T y) {
  if (y < x) x = y;
}
template <class T>
inline void Max(T &x, T y) {
  if (y > x) x = y;
}

/*

const int mod = 998244353;
inline int Add(int x) { return x >= mod ? x - mod : x; }
inline void Add(int &x, int y) { x += y; if (x >= mod) x -= mod; }
inline int Sub(int x) { return x < 0 ? x + mod : x; }
inline void Sub(int &x, int y) { x -= y; if (x < 0) x += mod; }
inline int Mul(int x, int y) { return (int)((li)x * y % mod); }
inline int Mul(int x, int y, int z) { return Mul(x, Mul(y, z)); }
int Pow(int x, int y) {
  int z = 1;
  for (; y; y >>= 1) {
    if (y & 1) z = Mul(z, x);
    x = Mul(x, x);
  }
  return z;
}
int Inv(int x) {
  return Pow(x, mod - 2);
}

*/

// ----------------------------------------

typedef long double real;

const int maxn = 50000;
const real scale = 1e3, pi = acos(-1.0L), eps = 1e-12L;

int n, m, ns;
real cx, cy;
real la[maxn], lb[maxn];

pair<real, real> seg[maxn];
real arcs[maxn * 2];

struct Seg {
  int l, r, id;
  bool operator < (const Seg &b) const {
    return l < b.l || (l == b.l && r < b.r);
  }
} segi[maxn];

int ord[maxn];

real Fix(real x) {
  while (x >= pi) x -= 2 * pi;
  while (x < -pi) x += 2 * pi;
  return x;
}

void MakeSegments(real radius) {
  ns = 0;

  for (int i = 0; i < n; ++i) {
    real down = sqrt(la[i] * la[i] + 1);
    real up = cy - la[i] * cx - lb[i];
    real dist = up / down;  // negative if below, positive if above
    if (abs(dist) > radius) continue;

    real alpha = atan2(la[i], 1) - pi / 2;
    if (dist < 0) {
      dist *= -1;
      alpha += pi;
    }

    real len_sqr = radius * radius - dist * dist;
    real delta = acos((radius * radius + dist * dist - len_sqr) /
                      (2 * radius * dist));
    if (dist < eps) delta = pi / 2;
    real beta1 = Fix(alpha + delta), beta2 = Fix(alpha - delta);
    if (beta1 > beta2) swap(beta1, beta2);
    seg[ns] = {beta1, beta2};

    arcs[2 * ns] = beta1;
    arcs[2 * ns + 1] = beta2;

    segi[ns].id = i;
    ++ns;
  }

  sort(arcs, arcs + 2 * ns);

  for (int i = 0; i < ns; ++i) {
    segi[i].l = (int)(lower_bound(arcs, arcs + 2 * ns, seg[i].first) - arcs);
    segi[i].r = (int)(lower_bound(arcs, arcs + 2 * ns, seg[i].second) - arcs);
  }
  sort(segi, segi + ns);

  for (int i = 0; i < ns; ++i) {
    ord[i] = i;
  }
  sort(ord, ord + ns, [](int i, int j) { return segi[i].r < segi[j].r; });
}

namespace bit {
  int N;
  int bit[2 * maxn];

  void Init(void) {
    N = 2 * ns;
    FILLA(bit, 0);
  }

  int Low(int i) {
    return i & -i;
  }

  void Add(int i, int x) {
    for (; i < N; i += Low(i + 1)) {
      bit[i] += x;
    }
  }

  int Sum(int i) {
    int sum = 0;
    for (; i >= 0; i -= Low(i + 1)) {
      sum += bit[i];
    }
    return sum;
  }
}

li Count(real radius) {
  MakeSegments(radius);

  bit::Init();
  using bit::Add;
  using bit::Sum;

  li ans = 0;
  int next = 0;
  for (int i = 0; i < ns; ++i) {
    int l = segi[i].l, r = segi[i].r;
    while (next < ns && segi[ord[next]].r < l) {
      Add(segi[ord[next]].r, -1);
      ++next;
    }
    ans += Sum(r);
    Add(r, 1);
  }

  return ans;
}

struct Cmp {
  bool operator () (const Seg &a, const Seg &b) const {
    if (a.r != b.r) return a.r < b.r;
    return a.id < b.id;
  }
};

void Get(int id, real &k, real &b) {
  k = la[id];
  b = lb[id];
}

real Cost(int id1, int id2) {
  real k1, b1, k2, b2;
  Get(id1, k1, b1);
  Get(id2, k2, b2);
  real x = (b2 - b1) / (k1 - k2);
  real y = k1 * x + b1;
  x -= cx;
  y -= cy;
  // printf("Cost(%d, %d): %Lf, %Lf\n", id1, id2, x, y);
  return sqrt(x * x + y * y);
}

pair<li, real> Output(real radius) {
  MakeSegments(radius);

  // printf("-------------------- Start Output %Lf --------------------\n", radius);
  // for (int i = 0; i < ns; ++i) {
  //   printf("seg %Lf %Lf\n", seg[i].first / pi, seg[i].second / pi);
  // }
  // for (int i = 0; i < ns; ++i) {
  //   printf("segi %d %d %d\n", segi[i].l, segi[i].r, i);
  // }

  set<Seg, Cmp> s;
  typedef set<Seg, Cmp>::iterator Iter;

  li cnt = 0;
  int next = 0;
  real sum = 0;
  for (int i = 0; i < ns; ++i) {
    int l = segi[i].l, r = segi[i].r;
    while (next < ns && segi[ord[next]].r < l) {
      s.erase(segi[ord[next]]);
      ++next;
    }
    for (Iter x = s.begin(); x != s.end(); ++x) {
      if (x->r > r) break;
      ++cnt;
      sum += Cost(x->id, segi[i].id);
    }
    s.insert(segi[i]);
  }

  // printf("cnt = %d\n", (int)cnt);
  return {cnt, sum};
}

real Solve(void) {
  real low = 0, high = 1e12;
  for (int i = 0; i < 80; ++i) {
    real mid = (low + high) * 0.5;
    if (Count(mid) > m) {
      high = mid;
    } else {
      low = mid;
    }
  }
  // printf("low = %Lf\n", low);
  real radius = low;
  pair<li, real> res = Output(radius);
  return res.second + (real)(m - res.first) * radius;
}

int main(void) {
  scanf("%d", &n);
  int x, y;
  scanf("%d%d%d", &x, &y, &m);
  cx = x / scale;
  cy = y / scale;

  for (int i = 0; i < n; ++i) {
    scanf("%d%d", &x, &y);
    la[i] = x / scale;
    lb[i] = y / scale;
  }
  real ans = Solve();
  printf("%.20Lf\n", ans);
  return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <set>

#define FILL(a, n, x) memset((a), (x), sizeof ((a)[0]) * (n))
#define COPY(a, n, b) memcpy((b), (a), sizeof ((a)[0]) * (n))
#define FILLA(a, x) memset((a), (x), sizeof (a))
#define COPYA(a, b) memcpy((b), (a), sizeof (a))

using namespace std;

typedef long long li;
typedef unsigned long long lu;
const li infl = ~0LLU >> 2;

template <class T>
inline void Min(T &x, T y) {
  if (y < x) x = y;
}
template <class T>
inline void Max(T &x, T y) {
  if (y > x) x = y;
}

/*

const int mod = 998244353;
inline int Add(int x) { return x >= mod ? x - mod : x; }
inline void Add(int &x, int y) { x += y; if (x >= mod) x -= mod; }
inline int Sub(int x) { return x < 0 ? x + mod : x; }
inline void Sub(int &x, int y) { x -= y; if (x < 0) x += mod; }
inline int Mul(int x, int y) { return (int)((li)x * y % mod); }
inline int Mul(int x, int y, int z) { return Mul(x, Mul(y, z)); }
int Pow(int x, int y) {
  int z = 1;
  for (; y; y >>= 1) {
    if (y & 1) z = Mul(z, x);
    x = Mul(x, x);
  }
  return z;
}
int Inv(int x) {
  return Pow(x, mod - 2);
}

*/

// ----------------------------------------

typedef double real;

const int maxn = 50000;
const real scale = 1e3, pi = acos(-1.0), eps = 1e-12;

int n, m, ns;
real cx, cy;
real la[maxn], lb[maxn];

pair<real, real> seg[maxn];
real arcs[maxn * 2];

struct Seg {
  int l, r, id;
  bool operator < (const Seg &b) const {
    return l < b.l || (l == b.l && r < b.r);
  }
} segi[maxn];

int ord[maxn];

real Fix(real x) {
  while (x >= pi) x -= 2 * pi;
  while (x < -pi) x += 2 * pi;
  return x;
}

void MakeSegments(real radius) {
  ns = 0;

  for (int i = 0; i < n; ++i) {
    real down = sqrt(la[i] * la[i] + 1);
    real up = cy - la[i] * cx - lb[i];
    real dist = up / down;  // negative if below, positive if above
    if (dist > radius) continue;

    real alpha = atan2(la[i], 1) - pi / 2;
    if (dist < 0) {
      dist *= -1;
      alpha += pi;
    }

    real len_sqr = radius * radius - dist * dist;
    real delta = acos((radius * radius + dist * dist - len_sqr) /
                      (2 * radius * dist));
    if (dist < eps) delta = pi / 2;
    real beta1 = Fix(alpha + delta), beta2 = Fix(alpha - delta);
    if (beta1 > beta2) swap(beta1, beta2);
    seg[ns] = {beta1, beta2};

    arcs[2 * ns] = beta1;
    arcs[2 * ns + 1] = beta2;

    ++ns;
  }

  sort(arcs, arcs + 2 * ns);

  for (int i = 0; i < ns; ++i) {
    segi[i].l = (int)(lower_bound(arcs, arcs + 2 * ns, seg[i].first) - arcs);
    segi[i].r = (int)(lower_bound(arcs, arcs + 2 * ns + 1, seg[i].second) -
                      arcs);
    segi[i].id = i;
  }
  sort(segi, segi + ns);

  for (int i = 0; i < ns; ++i) {
    ord[i] = i;
  }
  sort(ord, ord + ns, [](int i, int j) { return segi[i].r < segi[j].r; });
}

namespace bit {
  int N;
  int bit[2 * maxn];

  void Init(void) {
    N = 2 * ns;
    FILL(bit, N, 0);
  }

  int Low(int i) {
    return i & -i;
  }

  void Add(int i, int x) {
    for (; i < N; i += Low(i + 1)) {
      bit[i] += x;
    }
  }

  int Sum(int i) {
    int sum = 0;
    for (; i >= 0; i -= Low(i + 1)) {
      sum += bit[i];
    }
    return sum;
  }
}

li Count(real radius) {
  MakeSegments(radius);

  // printf("-------------------- Start Count %lf --------------------\n", radius);
  // for (int i = 0; i < ns; ++i) {
  //   printf("seg %lf %lf\n", seg[i].first / pi, seg[i].second / pi);
  // }
  // for (int i = 0; i < ns; ++i) {
  //   printf("segi %d %d %d\n", segi[i].l, segi[i].r, i);
  // }

  bit::Init();
  using bit::Add;
  using bit::Sum;

  li ans = 0;
  int next = 0;
  for (int i = 0; i < ns; ++i) {
    int l = segi[i].l, r = segi[i].r;
    while (next < ns && segi[ord[next]].r < l) {
      Add(segi[ord[next]].r, -1);
      ++next;
    }
    ans += Sum(r);
    Add(r, 1);
  }

  // printf("Count(%lf) = %lld\n", radius, ans);

  return ans;
}

struct Cmp {
  bool operator () (const Seg &a, const Seg &b) const {
    if (a.r != b.r) return a.r < b.r;
    return a.id < b.id;
  }
};

void Get(int id, real &k, real &b) {
  k = la[id];
  b = lb[id];
}

real Cost(int id1, int id2) {
  real k1, b1, k2, b2;
  Get(id1, k1, b1);
  Get(id2, k2, b2);
  real x = (b2 - b1) / (k1 - k2);
  real y = k1 * x + b1;
  x -= cx;
  y -= cy;
  // printf("cost(%d, %d): (%lf, %lf)\n", id1, id2, x, y);
  return sqrt(x * x + y * y);
}

pair<li, real> Output(real radius) {
  MakeSegments(radius);

  set<Seg, Cmp> s;
  typedef set<Seg, Cmp>::iterator Iter;

  li cnt = 0;
  int next = 0;
  real sum = 0;
  for (int i = 0; i < ns; ++i) {
    int l = segi[i].l, r = segi[i].r;
    while (next < ns && segi[ord[next]].r < l) {
      s.erase(segi[ord[next]]);
      ++next;
    }
    for (Iter x = s.begin(); x != s.end(); ++x) {
      if (x->r > r) break;
      ++cnt;
      sum += Cost(x->id, segi[i].id);
    }
    s.insert(segi[i]);
  }

  return {cnt, sum};
}

real Solve(void) {
  real low = 0, high = 1e12;
  for (int i = 0; i < 100; ++i) {
    real mid = (low + high) * 0.5;
    if (Count(mid) > m) {
      high = mid;
    } else {
      low = mid;
    }
  }
  // printf("low = %lf\n", low);
  real radius = low;
  pair<li, real> res = Output(radius);
  return res.second + (real)(m - res.first) * radius;
}

int main(void) {
  scanf("%d", &n);
  int x, y;
  scanf("%d%d%d", &x, &y, &m);
  cx = x / scale;
  cy = y / scale;

  for (int i = 0; i < n; ++i) {
    scanf("%d%d", &x, &y);
    la[i] = x / scale;
    lb[i] = y / scale;
  }
  real ans = Solve();
  printf("%.20lf\n", ans);
  return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <set>

#define FILL(a, n, x) memset((a), (x), sizeof ((a)[0]) * (n))
#define COPY(a, n, b) memcpy((b), (a), sizeof ((a)[0]) * (n))
#define FILLA(a, x) memset((a), (x), sizeof (a))
#define COPYA(a, b) memcpy((b), (a), sizeof (a))

using namespace std;

typedef long long li;
typedef unsigned long long lu;
const li infl = ~0LLU >> 2;

template <class T>
inline void Min(T &x, T y) {
  if (y < x) x = y;
}
template <class T>
inline void Max(T &x, T y) {
  if (y > x) x = y;
}

/*

const int mod = 998244353;
inline int Add(int x) { return x >= mod ? x - mod : x; }
inline void Add(int &x, int y) { x += y; if (x >= mod) x -= mod; }
inline int Sub(int x) { return x < 0 ? x + mod : x; }
inline void Sub(int &x, int y) { x -= y; if (x < 0) x += mod; }
inline int Mul(int x, int y) { return (int)((li)x * y % mod); }
inline int Mul(int x, int y, int z) { return Mul(x, Mul(y, z)); }
int Pow(int x, int y) {
  int z = 1;
  for (; y; y >>= 1) {
    if (y & 1) z = Mul(z, x);
    x = Mul(x, x);
  }
  return z;
}
int Inv(int x) {
  return Pow(x, mod - 2);
}

*/

// ----------------------------------------

typedef double real;

const int maxn = 50000;
const real scale = 1e3, pi = acos(-1.0L), eps = 1e-12L;

int n, m, ns;
real cx, cy;
real la[maxn], lb[maxn];

pair<real, real> seg[maxn];
real arcs[maxn * 2];

struct Seg {
  int l, r, id;
  bool operator < (const Seg &b) const {
    return l < b.l || (l == b.l && r < b.r);
  }
} segi[maxn];

int ord[maxn];

real Fix(real x) {
  while (x >= pi) x -= 2 * pi;
  while (x < -pi) x += 2 * pi;
  return x;
}

void MakeSegments(real radius) {
  ns = 0;

  for (int i = 0; i < n; ++i) {
    real down = sqrt(la[i] * la[i] + 1);
    real up = cy - la[i] * cx - lb[i];
    real dist = up / down;  // negative if below, positive if above
    if (abs(dist) > radius) continue;

    real alpha = atan2(la[i], 1) - pi / 2;
    if (dist < 0) {
      dist *= -1;
      alpha += pi;
    }

    real len_sqr = radius * radius - dist * dist;
    real delta = acos((radius * radius + dist * dist - len_sqr) /
                      (2 * radius * dist));
    if (dist < eps) delta = pi / 2;
    real beta1 = Fix(alpha + delta), beta2 = Fix(alpha - delta);
    if (beta1 > beta2) swap(beta1, beta2);
    seg[ns] = {beta1, beta2};

    arcs[2 * ns] = beta1;
    arcs[2 * ns + 1] = beta2;

    segi[ns].id = i;
    ++ns;
  }

  sort(arcs, arcs + 2 * ns);

  for (int i = 0; i < ns; ++i) {
    segi[i].l = (int)(lower_bound(arcs, arcs + 2 * ns, seg[i].first) - arcs);
    segi[i].r = (int)(lower_bound(arcs, arcs + 2 * ns, seg[i].second) - arcs);
  }
  sort(segi, segi + ns);

  for (int i = 0; i < ns; ++i) {
    ord[i] = i;
  }
  sort(ord, ord + ns, [](int i, int j) { return segi[i].r < segi[j].r; });
}

namespace bit {
  int N;
  int bit[2 * maxn];

  void Init(void) {
    N = 2 * ns;
    FILLA(bit, 0);
  }

  int Low(int i) {
    return i & -i;
  }

  void Add(int i, int x) {
    for (; i < N; i += Low(i + 1)) {
      bit[i] += x;
    }
  }

  int Sum(int i) {
    int sum = 0;
    for (; i >= 0; i -= Low(i + 1)) {
      sum += bit[i];
    }
    return sum;
  }
}

li Count(real radius) {
  MakeSegments(radius);

  bit::Init();
  using bit::Add;
  using bit::Sum;

  li ans = 0;
  int next = 0;
  for (int i = 0; i < ns; ++i) {
    int l = segi[i].l, r = segi[i].r;
    while (next < ns && segi[ord[next]].r < l) {
      Add(segi[ord[next]].r, -1);
      ++next;
    }
    ans += Sum(r);
    Add(r, 1);
  }

  return ans;
}

struct Cmp {
  bool operator () (const Seg &a, const Seg &b) const {
    if (a.r != b.r) return a.r < b.r;
    return a.id < b.id;
  }
};

void Get(int id, real &k, real &b) {
  k = la[id];
  b = lb[id];
}

real Cost(int id1, int id2) {
  real k1, b1, k2, b2;
  Get(id1, k1, b1);
  Get(id2, k2, b2);
  real x = (b2 - b1) / (k1 - k2);
  real y = k1 * x + b1;
  x -= cx;
  y -= cy;
  // printf("Cost(%d, %d): %Lf, %Lf\n", id1, id2, x, y);
  return sqrt(x * x + y * y);
}

pair<li, real> Output(real radius) {
  MakeSegments(radius);

  // printf("-------------------- Start Output %Lf --------------------\n", radius);
  // for (int i = 0; i < ns; ++i) {
  //   printf("seg %Lf %Lf\n", seg[i].first / pi, seg[i].second / pi);
  // }
  // for (int i = 0; i < ns; ++i) {
  //   printf("segi %d %d %d\n", segi[i].l, segi[i].r, i);
  // }

  set<Seg, Cmp> s;
  typedef set<Seg, Cmp>::iterator Iter;

  li cnt = 0;
  int next = 0;
  real sum = 0;
  for (int i = 0; i < ns; ++i) {
    int l = segi[i].l, r = segi[i].r;
    while (next < ns && segi[ord[next]].r < l) {
      s.erase(segi[ord[next]]);
      ++next;
    }
    for (Iter x = s.begin(); x != s.end(); ++x) {
      if (x->r > r) break;
      ++cnt;
      sum += Cost(x->id, segi[i].id);
    }
    s.insert(segi[i]);
  }

  // printf("cnt = %d\n", (int)cnt);
  return {cnt, sum};
}

real Solve(void) {
  real low = 0, high = 1e12;
  for (int i = 0; i < 80; ++i) {
    real mid = (low + high) * 0.5;
    if (Count(mid) > m) {
      high = mid;
    } else {
      low = mid;
    }
  }
  // printf("low = %Lf\n", low);
  real radius = low;
  pair<li, real> res = Output(radius);
  return res.second + (real)(m - res.first) * radius;
}

int main(void) {
  scanf("%d", &n);
  int x, y;
  scanf("%d%d%d", &x, &y, &m);
  cx = x / scale;
  cy = y / scale;

  for (int i = 0; i < n; ++i) {
    scanf("%d%d", &x, &y);
    la[i] = x / scale;
    lb[i] = y / scale;
  }
  real ans = Solve();
  printf("%.20lf\n", ans);
  return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <set>

#define FILL(a, n, x) memset((a), (x), sizeof ((a)[0]) * (n))
#define COPY(a, n, b) memcpy((b), (a), sizeof ((a)[0]) * (n))
#define FILLA(a, x) memset((a), (x), sizeof (a))
#define COPYA(a, b) memcpy((b), (a), sizeof (a))

using namespace std;

typedef long long li;
typedef unsigned long long lu;
const li infl = ~0LLU >> 2;

template <class T>
inline void Min(T &x, T y) {
  if (y < x) x = y;
}
template <class T>
inline void Max(T &x, T y) {
  if (y > x) x = y;
}

/*

const int mod = 998244353;
inline int Add(int x) { return x >= mod ? x - mod : x; }
inline void Add(int &x, int y) { x += y; if (x >= mod) x -= mod; }
inline int Sub(int x) { return x < 0 ? x + mod : x; }
inline void Sub(int &x, int y) { x -= y; if (x < 0) x += mod; }
inline int Mul(int x, int y) { return (int)((li)x * y % mod); }
inline int Mul(int x, int y, int z) { return Mul(x, Mul(y, z)); }
int Pow(int x, int y) {
  int z = 1;
  for (; y; y >>= 1) {
    if (y & 1) z = Mul(z, x);
    x = Mul(x, x);
  }
  return z;
}
int Inv(int x) {
  return Pow(x, mod - 2);
}

*/

// ----------------------------------------

typedef double real;

const int maxn = 50000;
const real scale = 1e3, pi = acos(-1.0L), eps = 1e-12L;

int n, m, ns;
real cx, cy;
real la[maxn], lb[maxn];

pair<real, real> seg[maxn];
real arcs[maxn * 2];

struct Seg {
  int l, r, id;
  bool operator < (const Seg &b) const {
    return l < b.l || (l == b.l && r < b.r);
  }
} segi[maxn];

int ord[maxn];

real Fix(real x) {
  while (x >= pi) x -= 2 * pi;
  while (x < -pi) x += 2 * pi;
  return x;
}

void MakeSegments(real radius) {
  ns = 0;

  for (int i = 0; i < n; ++i) {
    real down = sqrt(la[i] * la[i] + 1);
    real up = cy - la[i] * cx - lb[i];
    real dist = up / down;  // negative if below, positive if above
    if (abs(dist) > radius) continue;

    real alpha = atan2(la[i], 1) - pi / 2;
    if (dist < 0) {
      dist *= -1;
      alpha += pi;
    }

    real len_sqr = radius * radius - dist * dist;
    real delta = acos((radius * radius + dist * dist - len_sqr) /
                      (2 * radius * dist));
    if (dist < eps) delta = pi / 2;
    real beta1 = Fix(alpha + delta), beta2 = Fix(alpha - delta);
    if (beta1 > beta2) swap(beta1, beta2);
    seg[ns] = {beta1, beta2};

    arcs[2 * ns] = beta1;
    arcs[2 * ns + 1] = beta2;

    segi[ns].id = i;
    ++ns;
  }

  sort(arcs, arcs + 2 * ns);

  for (int i = 0; i < ns; ++i) {
    segi[i].l = (int)(lower_bound(arcs, arcs + 2 * ns, seg[i].first) - arcs);
    segi[i].r = (int)(lower_bound(arcs, arcs + 2 * ns, seg[i].second) - arcs);
  }
  sort(segi, segi + ns);

  for (int i = 0; i < ns; ++i) {
    ord[i] = i;
  }
  sort(ord, ord + ns, [](int i, int j) { return segi[i].r < segi[j].r; });
}

namespace bit {
  int N;
  int bit[2 * maxn];

  void Init(void) {
    N = 2 * ns;
    FILLA(bit, 0);
  }

  int Low(int i) {
    return i & -i;
  }

  void Add(int i, int x) {
    for (; i < N; i += Low(i + 1)) {
      bit[i] += x;
    }
  }

  int Sum(int i) {
    int sum = 0;
    for (; i >= 0; i -= Low(i + 1)) {
      sum += bit[i];
    }
    return sum;
  }
}

li Count(real radius) {
  MakeSegments(radius);

  bit::Init();
  using bit::Add;
  using bit::Sum;

  li ans = 0;
  int next = 0;
  for (int i = 0; i < ns; ++i) {
    int l = segi[i].l, r = segi[i].r;
    while (next < ns && segi[ord[next]].r < l) {
      Add(segi[ord[next]].r, -1);
      ++next;
    }
    ans += Sum(r);
    Add(r, 1);
  }

  return ans;
}

struct Cmp {
  bool operator () (const Seg &a, const Seg &b) const {
    if (a.r != b.r) return a.r < b.r;
    return a.id < b.id;
  }
};

void Get(int id, real &k, real &b) {
  k = la[id];
  b = lb[id];
}

real Cost(int id1, int id2) {
  real k1, b1, k2, b2;
  Get(id1, k1, b1);
  Get(id2, k2, b2);
  real x = (b2 - b1) / (k1 - k2);
  real y = k1 * x + b1;
  x -= cx;
  y -= cy;
  // printf("Cost(%d, %d): %Lf, %Lf\n", id1, id2, x, y);
  return sqrt(x * x + y * y);
}

pair<li, real> Output(real radius) {
  MakeSegments(radius);

  // printf("-------------------- Start Output %Lf --------------------\n", radius);
  // for (int i = 0; i < ns; ++i) {
  //   printf("seg %Lf %Lf\n", seg[i].first / pi, seg[i].second / pi);
  // }
  // for (int i = 0; i < ns; ++i) {
  //   printf("segi %d %d %d\n", segi[i].l, segi[i].r, i);
  // }

  set<Seg, Cmp> s;
  typedef set<Seg, Cmp>::iterator Iter;

  li cnt = 0;
  int next = 0;
  real sum = 0;
  for (int i = 0; i < ns; ++i) {
    int l = segi[i].l, r = segi[i].r;
    while (next < ns && segi[ord[next]].r < l) {
      s.erase(segi[ord[next]]);
      ++next;
    }
    for (Iter x = s.begin(); x != s.end(); ++x) {
      if (x->r > r) break;
      ++cnt;
      sum += Cost(x->id, segi[i].id);
    }
    s.insert(segi[i]);
  }

  // printf("cnt = %d\n", (int)cnt);
  return {cnt, sum};
}

real Solve(void) {
  real low = 0, high = 1e12;
  for (int i = 0; i < 80; ++i) {
    real mid = (low + high) * 0.5;
    if (Count(mid) > m) {
      high = mid;
    } else {
      low = mid;
    }
  }
  // printf("low = %Lf\n", low);
  real radius = low;
  pair<li, real> res = Output(radius - eps);
  return res.second + (real)(m - res.first) * radius;
}

int main(void) {
  scanf("%d", &n);
  int x, y;
  scanf("%d%d%d", &x, &y, &m);
  cx = x / scale;
  cy = y / scale;

  for (int i = 0; i < n; ++i) {
    scanf("%d%d", &x, &y);
    la[i] = x / scale;
    lb[i] = y / scale;
  }
  real ans = Solve();
  printf("%.20lf\n", ans);
  return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <set>

#define FILL(a, n, x) memset((a), (x), sizeof ((a)[0]) * (n))
#define COPY(a, n, b) memcpy((b), (a), sizeof ((a)[0]) * (n))
#define FILLA(a, x) memset((a), (x), sizeof (a))
#define COPYA(a, b) memcpy((b), (a), sizeof (a))

using namespace std;

typedef long long li;
typedef unsigned long long lu;
const li infl = ~0LLU >> 2;

template <class T>
inline void Min(T &x, T y) {
  if (y < x) x = y;
}
template <class T>
inline void Max(T &x, T y) {
  if (y > x) x = y;
}

/*

const int mod = 998244353;
inline int Add(int x) { return x >= mod ? x - mod : x; }
inline void Add(int &x, int y) { x += y; if (x >= mod) x -= mod; }
inline int Sub(int x) { return x < 0 ? x + mod : x; }
inline void Sub(int &x, int y) { x -= y; if (x < 0) x += mod; }
inline int Mul(int x, int y) { return (int)((li)x * y % mod); }
inline int Mul(int x, int y, int z) { return Mul(x, Mul(y, z)); }
int Pow(int x, int y) {
  int z = 1;
  for (; y; y >>= 1) {
    if (y & 1) z = Mul(z, x);
    x = Mul(x, x);
  }
  return z;
}
int Inv(int x) {
  return Pow(x, mod - 2);
}

*/

// ----------------------------------------

typedef long double real;

const int maxn = 50000;
const real scale = 1e3, pi = acos(-1.0L), eps = 1e-12L;

int n, m, ns;
real cx, cy;
real la[maxn], lb[maxn];

pair<real, real> seg[maxn];
real arcs[maxn * 2];

struct Seg {
  int l, r, id;
  bool operator < (const Seg &b) const {
    return l < b.l || (l == b.l && r < b.r);
  }
} segi[maxn];

int ord[maxn];

real Fix(real x) {
  while (x >= pi) x -= 2 * pi;
  while (x < -pi) x += 2 * pi;
  return x;
}

void MakeSegments(real radius) {
  ns = 0;

  for (int i = 0; i < n; ++i) {
    real down = sqrt(la[i] * la[i] + 1);
    real up = cy - la[i] * cx - lb[i];
    real dist = up / down;  // negative if below, positive if above
    if (abs(dist) > radius) continue;

    real alpha = atan2(la[i], 1) - pi / 2;
    if (dist < 0) {
      dist *= -1;
      alpha += pi;
    }

    real len_sqr = radius * radius - dist * dist;
    real delta = acos((radius * radius + dist * dist - len_sqr) /
                      (2 * radius * dist));
    if (dist < eps) delta = pi / 2;
    real beta1 = Fix(alpha + delta), beta2 = Fix(alpha - delta);
    if (beta1 > beta2) swap(beta1, beta2);
    seg[ns] = {beta1, beta2};

    arcs[2 * ns] = beta1;
    arcs[2 * ns + 1] = beta2;

    ++ns;
  }

  sort(arcs, arcs + 2 * ns);

  for (int i = 0; i < ns; ++i) {
    segi[i].l = (int)(lower_bound(arcs, arcs + 2 * ns, seg[i].first) - arcs);
    segi[i].r = (int)(lower_bound(arcs, arcs + 2 * ns, seg[i].second) - arcs);
    segi[i].id = i;
  }
  sort(segi, segi + ns);

  for (int i = 0; i < ns; ++i) {
    ord[i] = i;
  }
  sort(ord, ord + ns, [](int i, int j) { return segi[i].r < segi[j].r; });
}

namespace bit {
  int N;
  int bit[2 * maxn];

  void Init(void) {
    N = 2 * ns;
    FILLA(bit, 0);
  }

  int Low(int i) {
    return i & -i;
  }

  void Add(int i, int x) {
    for (; i < N; i += Low(i + 1)) {
      bit[i] += x;
    }
  }

  int Sum(int i) {
    int sum = 0;
    for (; i >= 0; i -= Low(i + 1)) {
      sum += bit[i];
    }
    return sum;
  }
}

li Count(real radius) {
  MakeSegments(radius);

  // printf("-------------------- Start Count %Lf --------------------\n", radius);
  // for (int i = 0; i < ns; ++i) {
  //   printf("seg %lf %lf\n", seg[i].first / pi, seg[i].second / pi);
  // }
  // for (int i = 0; i < ns; ++i) {
  //   printf("segi %d %d %d\n", segi[i].l, segi[i].r, i);
  // }

  bit::Init();
  using bit::Add;
  using bit::Sum;

  li ans = 0;
  int next = 0;
  for (int i = 0; i < ns; ++i) {
    int l = segi[i].l, r = segi[i].r;
    while (next < ns && segi[ord[next]].r < l) {
      Add(segi[ord[next]].r, -1);
      ++next;
    }
    ans += Sum(r);
    Add(r, 1);
  }

  // printf("Count(%Lf) = %lld\n", radius, ans);

  return ans;
}

struct Cmp {
  bool operator () (const Seg &a, const Seg &b) const {
    if (a.r != b.r) return a.r < b.r;
    return a.id < b.id;
  }
};

void Get(int id, real &k, real &b) {
  k = la[id];
  b = lb[id];
}

real Cost(int id1, int id2) {
  real k1, b1, k2, b2;
  Get(id1, k1, b1);
  Get(id2, k2, b2);
  real x = (b2 - b1) / (k1 - k2);
  real y = k1 * x + b1;
  x -= cx;
  y -= cy;
  return sqrt(x * x + y * y);
}

pair<li, real> Output(real radius) {
  MakeSegments(radius);

  set<Seg, Cmp> s;
  typedef set<Seg, Cmp>::iterator Iter;

  li cnt = 0;
  int next = 0;
  real sum = 0;
  for (int i = 0; i < ns; ++i) {
    int l = segi[i].l, r = segi[i].r;
    while (next < ns && segi[ord[next]].r < l) {
      s.erase(segi[ord[next]]);
      ++next;
    }
    for (Iter x = s.begin(); x != s.end(); ++x) {
      if (x->r > r) break;
      ++cnt;
      sum += Cost(x->id, segi[i].id);
    }
    s.insert(segi[i]);
  }

  // printf("cnt = %d\n", (int)cnt);
  return {cnt, sum};
}

real Solve(void) {
  real low = 0, high = 1e12;
  for (int i = 0; i < 100; ++i) {
    real mid = (low + high) * 0.5;
    if (Count(mid) > m) {
      high = mid;
    } else {
      low = mid;
    }
  }
  // printf("low = %Lf\n", low);
  real radius = low;
  pair<li, real> res = Output(radius);
  return res.second + (real)(m - res.first) * radius;
}

int main(void) {
  scanf("%d", &n);
  int x, y;
  scanf("%d%d%d", &x, &y, &m);
  cx = x / scale;
  cy = y / scale;

  for (int i = 0; i < n; ++i) {
    scanf("%d%d", &x, &y);
    la[i] = x / scale;
    lb[i] = y / scale;
  }
  real ans = Solve();
  printf("%.20Lf\n", ans);
  return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <set>

#define FILL(a, n, x) memset((a), (x), sizeof ((a)[0]) * (n))
#define COPY(a, n, b) memcpy((b), (a), sizeof ((a)[0]) * (n))
#define FILLA(a, x) memset((a), (x), sizeof (a))
#define COPYA(a, b) memcpy((b), (a), sizeof (a))

using namespace std;

typedef long long li;
typedef unsigned long long lu;
const li infl = ~0LLU >> 2;

template <class T>
inline void Min(T &x, T y) {
  if (y < x) x = y;
}
template <class T>
inline void Max(T &x, T y) {
  if (y > x) x = y;
}

typedef double real;

const int maxn = 50000;
const real scale = 1e3, pi = acos(-1.0L), eps = 1e-12L;

int n, m, ns;
real cx, cy;
real la[maxn], lb[maxn];

pair<real, real> seg[maxn];
real arcs[maxn * 2];

struct Seg {
  int l, r, id;
  bool operator < (const Seg &b) const {
    return l < b.l || (l == b.l && r < b.r);
  }
} segi[maxn];

int ord[maxn];

real Fix(real x) {
  while (x >= pi) x -= 2 * pi;
  while (x < -pi) x += 2 * pi;
  return x;
}

void MakeSegments(real radius) {
  ns = 0;

  for (int i = 0; i < n; ++i) {
    real down = sqrt(la[i] * la[i] + 1);
    real up = cy - la[i] * cx - lb[i];
    real dist = up / down;  // negative if below, positive if above
    if (abs(dist) > radius) continue;

    real alpha = atan2(la[i], 1) - pi / 2;
    if (dist < 0) {
      dist *= -1;
      alpha += pi;
    }

    real len_sqr = radius * radius - dist * dist;
    real delta = acos((radius * radius + dist * dist - len_sqr) /
                      (2 * radius * dist));
    if (dist < eps) delta = pi / 2;
    real beta1 = Fix(alpha + delta), beta2 = Fix(alpha - delta);
    if (beta1 > beta2) swap(beta1, beta2);
    seg[ns] = {beta1, beta2};

    arcs[2 * ns] = beta1;
    arcs[2 * ns + 1] = beta2;

    segi[ns].id = i;
    ++ns;
  }

  sort(arcs, arcs + 2 * ns);

  for (int i = 0; i < ns; ++i) {
    segi[i].l = (int)(lower_bound(arcs, arcs + 2 * ns, seg[i].first) - arcs);
    segi[i].r = (int)(lower_bound(arcs, arcs + 2 * ns, seg[i].second) - arcs);
  }
  sort(segi, segi + ns);

  for (int i = 0; i < ns; ++i) {
    ord[i] = i;
  }
  sort(ord, ord + ns, [](int i, int j) { return segi[i].r < segi[j].r; });
}

namespace bit {
  int N;
  int bit[2 * maxn];

  void Init(void) {
    N = 2 * ns;
    FILLA(bit, 0);
  }

  int Low(int i) {
    return i & -i;
  }

  void Add(int i, int x) {
    for (; i < N; i += Low(i + 1)) {
      bit[i] += x;
    }
  }

  int Sum(int i) {
    int sum = 0;
    for (; i >= 0; i -= Low(i + 1)) {
      sum += bit[i];
    }
    return sum;
  }
}

li Count(real radius) {
  MakeSegments(radius);

  bit::Init();
  using bit::Add;
  using bit::Sum;

  li ans = 0;
  int next = 0;
  for (int i = 0; i < ns; ++i) {
    int l = segi[i].l, r = segi[i].r;
    while (next < ns && segi[ord[next]].r < l) {
      Add(segi[ord[next]].r, -1);
      ++next;
    }
    ans += Sum(r);
    Add(r, 1);
  }

  return ans;
}

struct Cmp {
  bool operator () (const Seg &a, const Seg &b) const {
    if (a.r != b.r) return a.r < b.r;
    return a.id < b.id;
  }
};

void Get(int id, real &k, real &b) {
  k = la[id];
  b = lb[id];
}

real Cost(int id1, int id2) {
  real k1, b1, k2, b2;
  Get(id1, k1, b1);
  Get(id2, k2, b2);
  real x = (b2 - b1) / (k1 - k2);
  real y = k1 * x + b1;
  x -= cx;
  y -= cy;
  return sqrt(x * x + y * y);
}

pair<li, real> Output(real radius) {
  MakeSegments(radius);

  set<Seg, Cmp> s;
  typedef set<Seg, Cmp>::iterator Iter;

  li cnt = 0;
  int next = 0;
  real sum = 0;
  for (int i = 0; i < ns; ++i) {
    int l = segi[i].l, r = segi[i].r;
    while (next < ns && segi[ord[next]].r < l) {
      s.erase(segi[ord[next]]);
      ++next;
    }
    for (Iter x = s.begin(); x != s.end(); ++x) {
      if (x->r > r) break;
      ++cnt;
      sum += Cost(x->id, segi[i].id);
    }
    s.insert(segi[i]);
  }

  return {cnt, sum};
}

real Solve(void) {
  real low = 0, high = 1e12;
  for (int i = 0; i < 80; ++i) {
    real mid = (low + high) * 0.5;
    if (Count(mid) > m) {
      high = mid;
    } else {
      low = mid;
    }
  }
  real radius = low;
  pair<li, real> res = Output(radius - eps);
  return res.second + (real)(m - res.first) * radius;
}

int main(void) {
  scanf("%d", &n);
  int x, y;
  scanf("%d%d%d", &x, &y, &m);
  cx = x / scale;
  cy = y / scale;

  for (int i = 0; i < n; ++i) {
    scanf("%d%d", &x, &y);
    la[i] = x / scale;
    lb[i] = y / scale;
  }
  real ans = Solve();
  printf("%.20lf\n", ans);
  return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <set>

#define FILL(a, n, x) memset((a), (x), sizeof ((a)[0]) * (n))
#define COPY(a, n, b) memcpy((b), (a), sizeof ((a)[0]) * (n))
#define FILLA(a, x) memset((a), (x), sizeof (a))
#define COPYA(a, b) memcpy((b), (a), sizeof (a))

using namespace std;

typedef long long li;
typedef unsigned long long lu;
const li infl = ~0LLU >> 2;

template <class T>
inline void Min(T &x, T y) {
  if (y < x) x = y;
}
template <class T>
inline void Max(T &x, T y) {
  if (y > x) x = y;
}

/*

const int mod = 998244353;
inline int Add(int x) { return x >= mod ? x - mod : x; }
inline void Add(int &x, int y) { x += y; if (x >= mod) x -= mod; }
inline int Sub(int x) { return x < 0 ? x + mod : x; }
inline void Sub(int &x, int y) { x -= y; if (x < 0) x += mod; }
inline int Mul(int x, int y) { return (int)((li)x * y % mod); }
inline int Mul(int x, int y, int z) { return Mul(x, Mul(y, z)); }
int Pow(int x, int y) {
  int z = 1;
  for (; y; y >>= 1) {
    if (y & 1) z = Mul(z, x);
    x = Mul(x, x);
  }
  return z;
}
int Inv(int x) {
  return Pow(x, mod - 2);
}

*/

// ----------------------------------------

typedef long double real;

const int maxn = 50000;
const real scale = 1e3, pi = acos(-1.0L), eps = 1e-12L;

int n, m, ns;
real cx, cy;
real la[maxn], lb[maxn];

pair<real, real> seg[maxn];
real arcs[maxn * 2];

struct Seg {
  int l, r, id;
  bool operator < (const Seg &b) const {
    return l < b.l || (l == b.l && r < b.r);
  }
} segi[maxn];

int ord[maxn];

real Fix(real x) {
  while (x >= pi) x -= 2 * pi;
  while (x < -pi) x += 2 * pi;
  return x;
}

void MakeSegments(real radius) {
  ns = 0;

  for (int i = 0; i < n; ++i) {
    real down = sqrt(la[i] * la[i] + 1);
    real up = cy - la[i] * cx - lb[i];
    real dist = up / down;  // negative if below, positive if above
    if (abs(dist) > radius) continue;

    real alpha = atan2(la[i], 1) - pi / 2;
    if (dist < 0) {
      dist *= -1;
      alpha += pi;
    }

    real len_sqr = radius * radius - dist * dist;
    real delta = acos((radius * radius + dist * dist - len_sqr) /
                      (2 * radius * dist));
    if (dist < eps) delta = pi / 2;
    real beta1 = Fix(alpha + delta), beta2 = Fix(alpha - delta);
    if (beta1 > beta2) swap(beta1, beta2);
    seg[ns] = {beta1, beta2};

    arcs[2 * ns] = beta1;
    arcs[2 * ns + 1] = beta2;

    segi[ns].id = i;
    ++ns;
  }

  sort(arcs, arcs + 2 * ns);

  for (int i = 0; i < ns; ++i) {
    segi[i].l = (int)(lower_bound(arcs, arcs + 2 * ns, seg[i].first) - arcs);
    segi[i].r = (int)(lower_bound(arcs, arcs + 2 * ns, seg[i].second) - arcs);
  }
  sort(segi, segi + ns);

  for (int i = 0; i < ns; ++i) {
    ord[i] = i;
  }
  sort(ord, ord + ns, [](int i, int j) { return segi[i].r < segi[j].r; });
}

namespace bit {
  int N;
  int bit[2 * maxn];

  void Init(void) {
    N = 2 * ns;
    FILLA(bit, 0);
  }

  int Low(int i) {
    return i & -i;
  }

  void Add(int i, int x) {
    for (; i < N; i += Low(i + 1)) {
      bit[i] += x;
    }
  }

  int Sum(int i) {
    int sum = 0;
    for (; i >= 0; i -= Low(i + 1)) {
      sum += bit[i];
    }
    return sum;
  }
}

li Count(real radius) {
  MakeSegments(radius);

  bit::Init();
  using bit::Add;
  using bit::Sum;

  li ans = 0;
  int next = 0;
  for (int i = 0; i < ns; ++i) {
    int l = segi[i].l, r = segi[i].r;
    while (next < ns && segi[ord[next]].r < l) {
      Add(segi[ord[next]].r, -1);
      ++next;
    }
    ans += Sum(r);
    Add(r, 1);
  }

  return ans;
}

struct Cmp {
  bool operator () (const Seg &a, const Seg &b) const {
    if (a.r != b.r) return a.r < b.r;
    return a.id < b.id;
  }
};

void Get(int id, real &k, real &b) {
  k = la[id];
  b = lb[id];
}

real Cost(int id1, int id2) {
  real k1, b1, k2, b2;
  Get(id1, k1, b1);
  Get(id2, k2, b2);
  real x = (b2 - b1) / (k1 - k2);
  real y = k1 * x + b1;
  x -= cx;
  y -= cy;
  // printf("Cost(%d, %d): %Lf, %Lf\n", id1, id2, x, y);
  return sqrt(x * x + y * y);
}

pair<li, real> Output(real radius) {
  MakeSegments(radius);

  // printf("-------------------- Start Output %Lf --------------------\n", radius);
  // for (int i = 0; i < ns; ++i) {
  //   printf("seg %Lf %Lf\n", seg[i].first / pi, seg[i].second / pi);
  // }
  // for (int i = 0; i < ns; ++i) {
  //   printf("segi %d %d %d\n", segi[i].l, segi[i].r, i);
  // }

  set<Seg, Cmp> s;
  typedef set<Seg, Cmp>::iterator Iter;

  li cnt = 0;
  int next = 0;
  real sum = 0;
  for (int i = 0; i < ns; ++i) {
    int l = segi[i].l, r = segi[i].r;
    while (next < ns && segi[ord[next]].r < l) {
      s.erase(segi[ord[next]]);
      ++next;
    }
    for (Iter x = s.begin(); x != s.end(); ++x) {
      if (x->r > r) break;
      ++cnt;
      sum += Cost(x->id, segi[i].id);
    }
    s.insert(segi[i]);
  }

  // printf("cnt = %d\n", (int)cnt);
  return {cnt, sum};
}

real Solve(void) {
  real low = 0, high = 1e12;
  for (int i = 0; i < 50; ++i) {
    real mid = (low + high) * 0.5;
    if (Count(mid) > m) {
      high = mid;
    } else {
      low = mid;
    }
  }
  // printf("low = %Lf\n", low);
  real radius = low;
  pair<li, real> res = Output(radius);
  return res.second + (real)(m - res.first) * radius;
}

int main(void) {
  scanf("%d", &n);
  int x, y;
  scanf("%d%d%d", &x, &y, &m);
  cx = x / scale;
  cy = y / scale;

  for (int i = 0; i < n; ++i) {
    scanf("%d%d", &x, &y);
    la[i] = x / scale;
    lb[i] = y / scale;
  }
  real ans = Solve();
  printf("%.20Lf\n", ans);
  return 0;
}