第一天总体感受:
上午的内容是:模拟,递推,二分,贪心,排序,分治。除了在递推问题上感觉很难理解递推式的推导以外,其它的几种算法听的还算大致理解,至少思想是明白了。但是,在解答问题上还欠缺一些火候,还需要多加练习。总体来说,今天上午的听课状态不错,希望接下来的六天能够一直保持这种状态。
下午的测试:
第一题,看到题的时候感觉比较简单,写了一遍代码,运行了一下,发现样例过了,感觉没什么问题就看下面的题了,忽略了一种情况以至于只得到了10分。
第二题是递推的问题,不太会,果断跳第三题,回头再来看第二题的时候还是不会,在草纸上又是找规律又是推了半天,还算没有推出来,最后放弃了。
第三题是上午讲的一道题,二分法不怎么会,想了想用贪心算了下,感觉大部分数据应该都能过,结果挂了3个点,二分法的练习还差火候,回头得多练一练。
净月潭探险
【问题描述】
学习信息学奥赛的OIER都热爱探险,小明就是其中的一个,有一天小明在净月潭公园中一条充满许多有趣路标的路上探险。这条路就像数轴一样被标记了,小明开始的时候站在原点(x = 0)处。共有n个路标中,每个路标坐落于点 x1, x2, ..., xn。小明想在日落之前访问尽可能多的路标,现在距离日落还有T分钟,她每走一个单位长度,需要1分钟。
小明route照一个特殊的规则访问路标。即距离原点越近的路标,对小明越重要,他每次总是跑到未访问过的距离原点越近的路标。没有两个路标距离原点的距离相等。
请你帮助计算一下,小明在日落之前能够访问多少个路标。
【输入格式】
从文件explore.in中输入数据。
第 1 行: 两个整数 T,n
第 2..n+1 行: 路标i的位置 xi
【输出格式】
输出到文件explore.out中。
第 1 行: 小明在日落之前能够访问到的路标的个数
【样例输入】
25 5
10
-3
8
-7
1
【样例输出】
4
【数据规模与约定】
对于20%数据:T ≤ 25, n ≤ 15
对于40%数据: n ≤ 3000
对于100%数据:
1 ≤ n ≤ 50000; -100000 ≤ xi ≤ 100000; 1 ≤ T ≤ 1000000000
分析:用模拟的方法,加减xi的距离。
反思:比赛的时候心比较慌,没有冷静下来去思考正与负的加减问题,错的比较低级。
1 #include <cstdio> 2 #include <algorithm> 3 #include <cmath> 4 using namespace std; 5 #define MAXN 50005 6 int m[MAXN]; 7 bool cmp(int a1,int a2){return abs(a1)<abs(a2);} 8 int main() 9 { 10 freopen("explore.in","r",stdin); 11 freopen("explore.out","w",stdout); 12 int T,n,x=0,l=0; 13 scanf("%d%d",&T,&n); 14 for(int i=0;i<n;i++) 15 scanf("%d",&m[i]); 16 sort(m,m+n,cmp); 17 while(T-abs(m[x-1]-m[x])>0) 18 { 19 T=T-abs(m[x-1]-m[x]); 20 l++;x++; 21 } 22 printf("%d",l); 23 fclose(stdin); 24 fclose(stdout); 25 return 0; 26 }
净月潭航线
【问题描述】
净月潭国家森林公园是吉林省著名的5A级景区,因为公园中有一深潭而命名,这个深潭是圆形的,吉林省的OIER们要在圆潭的边上建N个码头,用以建立航线(可能为0条航线),航线只能是一个码头到另一个码头,并且多条航线之间不能相交,共用码头也算相交。请OIER们算一下,共有多少建立航线的方案?
【输入格式】
从文件route.in中输入数据。
一行一个数N
【输出格式】
输出到文件route.out中。
由于结果可能很大,你只需要输出这个答案mod 12345的值。
【样例输入】
4
【样例输出】
9
【数据规模与约定】
对于30%数据:N ≤ 10
对于50%数据:N ≤ 100
对于100%数据:N ≤ 1000
第二题考察的知识点是递推,总的来说,递推这块我学的一塌糊涂,讲的东西甚至都是半懂不懂,还需要多加练习,先把正确的代码贴上来,回头再仔细思考。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define N 1010 6 using namespace std; 7 int f[N]; 8 int main() 9 { 10 freopen("route.in","r",stdin); 11 freopen("route.out","w",stdout); 12 int n; 13 scanf("%d",&n); 14 int i,j; 15 f[0]=1; 16 f[1]=1; 17 for(i=2;i<=n;i++) 18 { 19 f[i]=f[i-1]; 20 for(j=2;j<=i;j++) 21 (f[i]+=f[j-2]*f[i-j])%=12345; 22 } 23 printf("%d",f[n]); 24 }
排干净月潭水塘
【问题描述】
净月潭公园里有n个水塘,因为要做吉林省OIER们的宿营地,需要把这n个水塘中的水排干,水塘中的水在自然条件下1个单位的时间可以蒸发A升水。现在买了1台抽水机,使用抽水机可以让你用1个单位的时间使每个水塘除开自然蒸发的A升水外,还可抽B升水,但在1个单位的时间内只能对1个水塘使用。
要你求出排干所有水塘的最少时间(水塘中的水为0时为排干)。
【输入格式】
从文件dry.in中输入数据。
第一行N,A,B;
接下来N行,a1,a2,…aN每行一个数,表示每个水塘中水的升数。
(1<=ai,A,B<=500000,1<=N<=500000)。
【输出格式】
输出到文件dry.out中。
一行一个整数,表示排干所有水塘的最少时间。
【样例输入】
3 2 1
1
2
3
【样例输出】
1
【样例说明】
第1个单位时间内,用机器抽取第3个水塘1升水,此外,所有水塘自然蒸发2升水。
【数据规模与约定】
对于10%数据:N ≤ 5
对于40%数据:N ≤ 5000
对于100%数据:N ≤ 500000
算法:二分法
考试的时候没有想明白,用贪心法得了70分
1 //贪心-%70数据 2 #include <cstdio> 3 #include <algorithm> 4 #include <cmath> 5 int s[500005]; 6 using namespace std; 7 int main() 8 { 9 freopen("dry.in","r",stdin); 10 freopen("dry.out","w",stdout); 11 int n,a,b,c=0,m=0,z,x; 12 bool k=0; 13 scanf("%d%d%d",&n,&a,&b); 14 for(int i=0;i<n;i++) 15 { 16 scanf("%d",&s[i]); 17 if(i==0) z=i; 18 else 19 if(s[i]>s[z])z=i; 20 } 21 while(1) 22 { 23 k=0; 24 s[z]=s[z]-a-b; 25 x=z; 26 for(int i=0;i<n;i++) 27 { 28 if(i!=x) 29 s[i]-=a; 30 if(s[i]>s[z])z=i; 31 if(s[i]<0)s[i]=0; 32 if(s[i]>0)k=1; 33 } 34 c++; 35 if(k==0) break; 36 37 } 38 printf("%d",c); 39 fclose(stdin); 40 fclose(stdout); 41 return 0; 42 43 }
1 //二分:100%数据 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstdio> 5 using namespace std; 6 long wet[500000],a,b,n,best; 7 8 int sr(void) 9 { 10 long i; 11 scanf("%d %d %d\n",&n,&a,&b); 12 for(i=0;i<n;i++){scanf("%d\n",&wet[i]);} 13 return 0; 14 } 15 16 int zx(void) 17 { 18 long i,j,t,w,m; 19 t=0,w=500000; 20 best=2147483647; 21 while(t<w) 22 { 23 m=(t+w+1)/2; 24 long temp=0; 25 for(i=0;i<n;i++) 26 { 27 if((wet[i]+a-1)/a>m) 28 { 29 temp+=(wet[i]-m*a+b-1)/b; 30 } 31 } 32 if(temp<=m) 33 { 34 if(m<best){best=m;} 35 w=m-1; 36 } 37 else{t=m;} 38 } 39 return 0; 40 } 41 42 int sc(void) 43 { 44 printf("%d\n",best); 45 return 0; 46 } 47 48 int main(void) 49 { 50 freopen("dry.in","r",stdin); 51 freopen("dry.out","w",stdout); 52 sr(); 53 zx(); 54 sc(); 55 return 0; 56 }
收获:
头一天的学习,了解到了几种基础的算法,走出来以前练代码能力的时候一直用暴力写的尴尬。我觉得,现在我应该可以尝试着去做一些算法类的题了。递推,递归这块,还是很头疼,做的题少的缘故吧,总之看着别人的递推式,为什么这么样写,就是不明白,估计我还需要一段时间的磨练才能做到真正的掌握。做题的时候一定要静下心来冷静的分析问题,不能慌。