codechef营养题 第三弹
第三弾が始まる!
codechef problems 第三弹
一、Motorbike Racing
题面
It's time for the annual exciting Motorbike Race in Byteland.
There are N motorcyclists taking part in the competition. Johnny is watching the race. At the present moment (time 0), Johnny has taken note of the current velocity and position of each motorcyclist.
Johnny wants to know at a given point of time, which motorcyclist is in a specific place in the rank list. Please help him!
If at any given time two motorcyclists are in same position, the motorcyclist with the smaller index will be placed before the one with the larger index.
To make the problem simple, Johnny assumes that each motorcyclist is moving at a constant velocity.
Input
The first line contains a number t (about 10) which is the number of test cases. Then t test cases follow. Each test case has the following form.
The first line of the test case contains a number N (1 <= N <= 2000), the number of motorcyclists.
The i-th line in the next N lines contains two numbers, v and x, which are the velocity and the current position of the i-th motorcyclist (1 <= v, x <= 100,000).
The next line contains a number Q (1 <= Q <= 2000), the number of time queries.
Each line in the next Q lines contains two numbers, t (1 <= t <= 1,000,000,000) and k (1 <= k <= n), representing the query: "at time t, which motorcyclist is positioned k-th in the rank list?"
Output
For each test case, print Q lines, with each line containing the index of the motorcyclist for the corresponding query.
Remember to print a new line after each test case.
Example
Input:
1 4 2 100 3 50 4 60 5 1 4 1 1 50 2 60 4 100 1
Output:
1 4 1 4
Description
一列摩托车,描述为二元组,(速度,初始位移)
给出一些询问,问在某个时刻下,位移第k大的摩托的编号
Solution
暴力去修改,之后全部排序的话,O(nqlogn),超时
部分排序的话,用nth_element可以水过,而且很快
这里的解给出的是O(nq+n*n)的
即,离线来做
考虑到车子的变化是有限的,即超车次数不超过n*n
我们对询问排序,每次对每辆车冒泡
这样就可以正确过了
codechef上目前排名第5 哦
rank 5 code
#include <stdio.h> #include <algorithm> #define RG register #define N 2010 #define MAXBUF 1<<22 #define L long long #define gec() ((S==T&&(T=(S=B)+fread(B,1,MAXBUF,stdin),S==T))?0:*S++) #define puc() fwrite(buff,1,itrr-buff,stdout),itrr=buff; char B[MAXBUF],*S=B,*T=B,buff[MAXBUF],*itrr=buff;int stt[110]; template<class Type>inline void Rin(RG Type &aa){ aa=0;bool bb=0;char cc; for(cc=gec();(cc<'0'||cc>'9')&&cc!='-';cc=gec()) ; for(cc=='-'?bb=1:aa=cc-'0',cc=gec();'0'<=cc&&cc<='9';cc=gec()) aa=aa*10+cc-'0'; aa=bb?-aa:aa; } template<class Type>inline void Cat(RG Type aa,RG char cc='\n'){ RG int O=0; if(!aa) *itrr++='0'; else{ aa<0?aa=-aa,*itrr++='-':1; for(;aa;stt[++O]=aa%10,aa/=10) ; for(;O;*itrr++='0'+stt[O--]) ; } *itrr++=cc; } int kase,n,m,ans[N]; struct bike{ int v,x,ind; L now; bool operator < (bike &o)const{ return now>o.now||now==o.now&&ind<o.ind; } }a[N]; struct resq{ int t,k,ind; bool operator < (resq &o)const{ return t<o.t; } }b[N]; #define set_file(File) freopen(#File".in","r",stdin),freopen(#File".out","w",stdout) #define close_file() fclose(stdin),fclose(stdout) int main(){ set_file(cc mot rac); Rin(kase); while(kase--){ Rin(n); for(RG int i=1;i<=n;i++) Rin(a[i].v),Rin(a[i].x),a[i].ind=i; Rin(m); for(RG int i=1;i<=m;i++) Rin(b[i].t),Rin(b[i].k),b[i].ind=i; std::sort(b+1,b+1+m); for(RG int i=1;i<=n;i++) a[i].now=(L)a[i].v*b[1].t+a[i].x; std::sort(a+1,a+1+n); ans[b[1].ind]=a[b[1].k].ind; for(RG int i=2;i<=m;i++){ RG int t=b[i].t,k=b[i].k; for(RG int j=1;j<=n;j++) a[j].now=(L)a[j].v*t+a[j].x; for(RG int j=2;j<=n;j++){ RG int x=j; while(x>1&&a[x]<a[x-1]){ bike tmp=a[x]; a[x]=a[x-1]; a[x-1]=tmp; x--; } } ans[b[i].ind]=a[k].ind; } for(RG int i=1;i<=m;i++) Cat(ans[i]); if(kase) *itrr++='\n'; } puc(); close_file(); return 0; }
二、MileStones
题面
Once upon a time, there was a Kingdom of Seven Roads. Besides a fancy name, it actually had exactly 7 straight roads. Its residents wanted to keep track of the distances they traveled so they placed milestones along some roads. The roads slowly deteriorated and disappeared but some milestones remained. Archeologists documented remaining milestones and want to reconstruct the kingdom, starting with its main road. Help them by finding the maximum number of collinear milestones.
Input
The first line contains a single integer T, the number of test cases. The first line of each testcase contains the number of documented milestones N. Following lines give the coordinates (Xi, Yi) of those milestones. Coordinates of all milestones will be different.
Output
For each test case, output the maximum number of collinear milestones.
Constraints
- T <= 30
- 1 <= N <= 10 000
- -15 000 <= Xi, Yi <= 15 000
Example
Input:
2 5 0 0 1 0 2 0 1 1 3 1 2 1 1 10 10
Output:
3 2
Description
给定平面内N个点,N<=1W,已知有不超过7条直线可以全部覆盖它们,求一条覆盖点的数量最多的直线
T<=30
Solution
考虑概率算法
可以简单地证明一个性质
性质1:7条直线中经过点最多的直线覆盖的点数>=N/7
任选一条直线(任意两点确定一条直线),和该直线重合的概率为1/49,那么不抽到该直线的概率为48/49
选k次,不重合的概率为(48/49)^k,若抽150次,不重合概率为2.9552076050124080563364456925748e-254,非常小o
目前codechef上排名rank1,叫我快男
#include <time.h> #include <stdio.h> #include <stdlib.h> #define RG register #define MaxN 10010 #define MAXBUF 1<<22 #define gec() ((I==J&&(J=(I=B)+fread(B,1,MAXBUF,stdin),I==J))?0:*I++) #define output() fwrite(buff,1,itrr-buff,stdout),itrr=buff #define set_file(File) freopen(File".in","r",stdin),freopen(File".out","w",stdout) #define close_file() fclose(stdin),fclose(stdout) #define dmax(a,b) ((a)>(b)?(a):(b)) char B[MAXBUF],*I=B,*J=B,buff[MAXBUF],*itrr=buff;int stt[100]; template<class Type> inline void Rin(RG Type &aa){ aa=0;RG bool bb=0;RG char cc; for(cc=gec();(cc<'0'||cc>'9')&&cc!='-';cc=gec()) ; for(cc=='-'?bb=1:aa=cc-'0',cc=gec();'0'<=cc&&cc<='9';cc=gec()) aa=aa*10+cc-'0'; aa=bb?-aa:aa; } template<class Type> inline void Cat(RG Type aa,RG char cc='\n'){ RG int O=0; if(!aa) *itrr++='0'; else{ (aa<0)?aa=-aa,*itrr++='-':1; for(;aa;stt[++O]=aa%10,aa/=10) ; for(;O;*itrr++='0'+stt[O--]) ; } *itrr++=cc; } int kase,n,ans,x[MaxN],y[MaxN]; int main(){ srand(time(0)); set_file("cc Mile Stones"); Rin(kase); while(kase--){ ans=1; Rin(n); for(RG int i=0;i<n;i++) Rin(x[i]),Rin(y[i]); for(RG int iter=0;iter<150;iter++){ RG int u=rand()%n,v=rand()%n,cnt=0; if(u==v)continue; RG int x1=x[v]-x[u],y1=y[v]-y[u]; for(RG int i=0;i<n;i++){ RG int x2=x[i]-x[u],y2=y[i]-y[u]; if(x1*y2-x2*y1==0)cnt++; } ans=dmax(ans,cnt); } Cat(ans); } output(); close_file(); return 0; }