2016级新生周赛(七)题解
1.XXX班的团事活动简单的贪心问题,想要租借的独木舟数最少,最容易想到的方法就是让体重最大的和体重最小的在一个独木舟上(当然了,前提是两个人的体重之和都不超过独木舟的最大承载量)剩下就是单独一个人做一条独木舟即可。先按人的体重大小排序,然后合理分配即可#include“stdio.h”#include"algorithm"usingnamespacestd;int main(){ inta[205]; intn,w,i,t,ans,k; scanf("%d",&t); while(t--) { ans=0;k=1; scanf("%d%d",&w,&n); for(i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+n+1); for(i=n;i>=k;i--) { if(a[i]>=w) ans++; else { while(a[i]+a[k]<=w&&i>k) { ans++; k++; i--; } if(a[i]+a[k]>w&&i>k) ans++; if(ik) ans++; } } printf("%d\",ans); }} 2.又是郊游水题一道。。。简单想一下相遇的过程,公式就出来了#include"stdio.h"int main(){ intt; doublem,x,y,z; scanf("%d",&t); while(t--) { scanf("%lf%lf%lf%lf",&m,&x,&y,&z); printf("%.2f\",mx/(y-x)z); }} 3.简单的数学问题周长最小,肯定是相邻边的差最小了,想到这个地方,问题自然就解决了#include"stdio.h"#include"math.h"typedeflonglongll;#definemaxn50005int main(){ lln,i,j; scanf("%lld",&n); llm=(int)sqrt((double)n)+1; for(i=m;i>0;i--) if(n%i0) { printf("%lld\",2(i+n/i)); break; }} 4.神奇的井题目还是很容易看懂和理解的,但是因为数据很大,所以说难点就是怎样用O(n)的方法巧妙地解决这道题,很多人都会想到一个一个放,然后来枚举剩下的情况,最差是O(n^2)的复杂度,要是这样的话就变成水题了,所以放了很多大数的测实例(50005000的,很大吧),最好的放大就是简单的预处理一下,从底到顶判断。预处理保证下层井宽小于等于上层:即a[i]=min(a[i],a[i-1]);为什么要这样呢,可以想想看,当前深度时井的宽度是不是只有小于更深处的井宽时才对下边有影响,想到这里边很轻松的解决了这道题了,剩下的只需便利一遍比较大小即可了#include"stdio.h"#include"algorithm"#include “limits.h”#include ““math.h”usingnamespacestd; #definemaxn50005 typedeflonglongll; lla[maxn],b[maxn]; int main() { lln,m,i,j,sum=0; scanf("%lld%lld",&n,&m); a[0]=INT_MAX; for(i=1;i<=n;i++) { scanf("%lld",&a[i]); a[i]=min(a[i],a[i-1]); } for(i=1;i<=m;i++) { scanf("%lld",&b[i]); while(a[n] if(n>0)sum++,n--; } printf("%lld\",sum); }5.cds的大数阶乘和平常所做的简单阶乘不同,唯一的区别就是如此大的数肯定是不能简单的累乘了,因为必定会爆longlong,更不用说int了,所以这里就是考察是否可以用一个巧妙地方法来模拟这一过程,呢就是模拟乘法了。这里给你一种构造万进制模拟乘法的方法。(方法不唯一)#include“stdio.h”intlen;voidRedix(intx,intr[]);intmain(void){ intn,i; while(scanf("%d",&n)!=EOF) { intr[20000]={1}; len=0; for(i=1;i<=n;i++) Redix(i,r); printf("%d",r[len]); for(i=len-1;i>=0;i--) printf("d",r[i]); printf("\"); } return0;} voidRedix(intx,intr[]) { intup,i; up=0; for(i=0;i<=len;i++) { r[i]=r[i]*x+up; up=r[i]/10000; if(r[i]>=10000) r[i]%=10000; } if(up>0) r[++len]=up;} 6.ykc`s easy exam简单的规律题,除了0要特判以外。。。规律是84268426……所以只用余4即可#include“stdio.h”int main(){ intn; scanf("%d",&n); if(n0) printf("1\"); elseif(n%41) printf("8\"); elseif(n%42) printf("4\"); elseif(n%43) printf("2\"); else printf("6\");}7.zy最爱的足球赛题意很明确,典型的贪心思路,要想一天内安排的足球赛尽可能多,按开始时间尽可能早的话肯定是不科学的,可以想想看,假如有一场球赛早上1点就开始了,但是晚上12点才结束,呢么按照之前的思路的话只能安排一场肯定是不行的,所以你自然而然的就能想到按照结束时间排序,当前最早结束的球赛肯定是要被安排在内的,这样的话问题自然而然就解决了,一波排序,然后用一个游历指针标记上场比赛的结束时间即可。#include#includeusingnamespacestd;structnode{intx,y;}a[1005];intmain(){inti,j,t,n,p;scanf("%d",&t);while(t--){p=0;intans=0; nodetemp;scanf("%d",&n);for(i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y); for(i=1;i for(j=i;j<=n;j++) { if(a[i].y>a[j].y) { temp=a[i]; a[i]=a[j]; a[j]=temp; } }for(i=1;i<=n;i++)if(a[i].x>p){p=a[i].y;ans++;}printf("%d\",ans);}}8.最小的距离之和简单的思维题,其实就是找到中位数即可,然后把小数部分去掉就行了#include"stdio.h"#include"limits.h"#include"math.h"typedeflonglongll;#definemaxn10005lla[maxn];int main(){ lln,i,j,mins=INT_MAX; doublem,sum=0; scanf("%lld",&n); for(i=1;i<=n;i++) scanf("%lld",&a[i]); sort(a+1,a+n+1); if(n%2)m=a[n/2+1]; elsem=(a[n/2+1]+a[n/2])/2.0; for(i=1;i<=n;i++) sum+=fabs(m-a[i]); printf("%.0f\",sum);}