Draw Something http://acm.hdu.edu.cn/showproblem.php?pid=4450
o(n)统计输入每个数的平方和。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 int main(){ 3 int n,x; 4 while(~scanf("%d",&n),n){ 5 int ans=0; 6 while(n--){ 7 scanf("%d",&x); 8 ans+=x*x; 9 } 10 printf("%d ",ans); 11 } 12 return 0; 13 }
Physical Examination http://acm.hdu.edu.cn/showproblem.php?pid=4442
有n个任务要完成,每个任务有x,y两个权值。完成某个任务所需的时间是x+t*y,其中t是当前的时间,也就是之前所有任务的时间总和。为了使总时间小。
贪心的算法。
考虑x,x不论放哪里,对于当前任务的贡献值都是x,但是对后面所有任务的t都有贡献,所以x越小越先做,这样后面t就会相对较小,使得后面任务所需时间也小。
考虑y,y放哪里,对当前任务贡献值是t*y,也就是说y越大,越要先做,因为先做的t肯定比后做的小,而且这样也会使得对之后的贡献值减小。
综上所诉,x越小y越大,那么越优先,定义一个优先系数用x/y表示,系数越小,越先做。因为可能有除不尽的情况,我又不想用double,等下精度又gg,所以转化了一下。
a.x/a.y < b.x/b.y => a.x*b.y <b.x*a.y
o(n*log(n))
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 typedef __int64 LL; 5 const int M=100010; 6 const int mod=365*24*60*60; 7 struct G{ 8 LL x,y; 9 friend bool operator <(G a,G b){ 10 return a.x*b.y<b.x*a.y; 11 } 12 }p[M]; 13 int main(){ 14 int n,x; 15 while(~scanf("%d",&n),n){ 16 for(int i=0;i<n;i++){ 17 scanf("%I64d%I64d",&p[i].x,&p[i].y); 18 } 19 sort(p,p+n); 20 LL ans=0,now=0; 21 for(int i=0;i<n;i++){ 22 ans+=p[i].x+now*p[i].y; 23 ans%=mod; 24 now=ans; 25 } 26 printf("%I64d ",ans); 27 } 28 return 0; 29 }
Dressing http://acm.hdu.edu.cn/showproblem.php?pid=4451
根据输入p=10^6处理出两两之间是否有关系,有关系就不能匹配。然后n^2的处理出每一个pants能匹配几个shoes,然后n^2的枚举clothes 和 pants,通过之前处理的值可以直接算出包含这对衣服裤子的匹配数。
总的复杂度还是o(n^2)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #define mt(a,b) memset(a,b,sizeof(a)) 4 const int M=1010; 5 int sum[M]; 6 bool ctop[M][M],ptos[M][M]; 7 char a[16],b[16]; 8 int main(){ 9 int n,m,k,p,x,y; 10 while(~scanf("%d%d%d",&n,&m,&k),n|m|k){ 11 scanf("%d",&p); 12 mt(ctop,0); 13 mt(ptos,0); 14 while(p--){ 15 scanf("%s%d%s%d",a,&x,b,&y); 16 if(a[0]=='c'){ 17 ctop[x][y]=true; 18 } 19 else{ 20 ptos[x][y]=true; 21 } 22 } 23 mt(sum,0); 24 for(int i=1;i<=m;i++){ 25 for(int j=1;j<=k;j++){ 26 if(!ptos[i][j]){ 27 sum[i]++; 28 } 29 } 30 } 31 int ans=0; 32 for(int i=1;i<=n;i++){ 33 for(int j=1;j<=m;j++){ 34 if(!ctop[i][j]){ 35 ans+=sum[j]; 36 } 37 } 38 } 39 printf("%d ",ans); 40 } 41 return 0; 42 }
Running Rabbits http://acm.hdu.edu.cn/showproblem.php?pid=4452
o(n)的模拟题。题目怎么说怎么做。题目说11,和nn有两人有初始方向,告诉你每秒的速度,几秒左转一次,撞墙了就向后转把剩余步数走完,两个相遇在同一个点交换方向,万一正好要左转那就忽略这次左转。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 struct G{ 5 int x,y,dir,s,t; 6 }A,B; 7 int change(int x){ 8 if(x==0) return 2; 9 if(x==1) return 3; 10 if(x==2) return 1; 11 if(x==3) return 0; 12 } 13 void turnleft(G &C){ 14 C.dir=change(C.dir); 15 } 16 int getdir(char c){ 17 if(c=='E') return 0; 18 if(c=='W') return 1; 19 if(c=='N') return 2; 20 if(c=='S') return 3; 21 } 22 int dx[]={0,0,-1,1}; 23 int dy[]={1,-1,0,0}; 24 int n,k; 25 int really(int x){ 26 if(x>=1&&x<=n) return x; 27 if(x>n) return n-(x-n); 28 if(x<1) return 1+(1-x); 29 } 30 void onestep(G &C){ 31 int tx=C.x+dx[C.dir]*C.s; 32 int ty=C.y+dy[C.dir]*C.s; 33 C.x=really(tx); 34 C.y=really(ty); 35 if(C.x!=tx||C.y!=ty){ 36 C.dir^=1; 37 } 38 } 39 int main(){ 40 char op[4]; 41 while(~scanf("%d",&n),n){ 42 scanf("%s%d%d",op,&A.s,&A.t); 43 A.dir=getdir(op[0]); 44 A.x=A.y=1; 45 scanf("%s%d%d",op,&B.s,&B.t); 46 B.dir=getdir(op[0]); 47 B.x=B.y=n; 48 scanf("%d",&k); 49 for(int i=1;i<=k;i++){ 50 onestep(A); 51 onestep(B); 52 if(A.x==B.x&&A.y==B.y){ 53 swap(A.dir,B.dir); 54 continue; 55 } 56 if(!(i%A.t)) turnleft(A); 57 if(!(i%B.t)) turnleft(B); 58 } 59 printf("%d %d %d %d ",A.x,A.y,B.x,B.y); 60 } 61 return 0; 62 }
Crazy Tank http://acm.hdu.edu.cn/showproblem.php?pid=4445
有n个炮弹,每个炮弹有各自的速度,炮的角度可以任意选,但是选了之后就不能改变了。敌方有区间L1R1,我方有区间L2R2。现在问在保证没有炮弹进入我方的情况下,最多能有几个炮弹进入敌方区间。
算法,暴力枚举角度θ,算这个角度下满足题意有几个。枚举了1000个角度过了,复杂度200*1000*testcase。
抛物线速度时间都是对称的。枚举的是炮和y轴的角度θ。在这个角度下水平速度Vx=Vi*sin(θ) 垂直速度 Vy=Vi*cos(θ)
达到最高点的时间 t1=Vy/g g=9.8重力加速度
对于对称点到地面 距离H=Vy*t2+1/2*g*t2*t2
解出t2 总时间 t = 2*t1+t2 水平位移 s=Vx*t
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 using namespace std; 5 const double eps=1e-8; 6 const double pi=acos(-1.0); 7 const double g=9.8; 8 const int M=210; 9 double v[M],H,L1,R1,L2,R2; 10 void solve2ci(double A,double B,double C,double &x1,double &x2){ 11 double delta=B*B-4*A*C; 12 x1=(-B+sqrt(delta))/(2*A); 13 x2=(-B-sqrt(delta))/(2*A); 14 } 15 int main(){ 16 int n; 17 while(~scanf("%d",&n),n){ 18 scanf("%lf%lf%lf%lf%lf",&H,&L1,&R1,&L2,&R2); 19 for(int i=0;i<n;i++){ 20 scanf("%lf",&v[i]); 21 } 22 double add=180.0/1000; 23 double xita,Vx,Vy,t1,t2,t,s,x1,x2,A=0.5*g,B,C=-H; 24 int ans=0; 25 for(double x=0;x<180;x+=add){ 26 xita=x*pi/180; 27 int sum=0; 28 for(int i=0;i<n;i++){ 29 Vx=v[i]*sin(xita); 30 Vy=v[i]*cos(xita); 31 B=Vy; 32 solve2ci(A,B,C,x1,x2); 33 t1=Vy/g; 34 t2=max(x1,x2); 35 t=t1+t1+t2; 36 s=Vx*t; 37 if(L2-eps<s&&s<R2+eps){ 38 sum=0; 39 break; 40 } 41 if(L1-eps<s&&s<R1+eps){ 42 sum++; 43 } 44 } 45 ans=max(ans,sum); 46 } 47 printf("%d ",ans); 48 } 49 return 0; 50 }
end