首页 > 代码库 > 吉林省2017年冬令营DAY1

吉林省2017年冬令营DAY1

第一天总体感受:

   上午的内容是:模拟,递推,二分,贪心,排序,分治。除了在递推问题上感觉很难理解递推式的推导以外,其它的几种算法听的还算大致理解,至少思想是明白了。但是,在解答问题上还欠缺一些火候,还需要多加练习。总体来说,今天上午的听课状态不错,希望接下来的六天能够一直保持这种状态。

下午的测试:

  第一题,看到题的时候感觉比较简单,写了一遍代码,运行了一下,发现样例过了,感觉没什么问题就看下面的题了,忽略了一种情况以至于只得到了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 }

 收获:

  头一天的学习,了解到了几种基础的算法,走出来以前练代码能力的时候一直用暴力写的尴尬。我觉得,现在我应该可以尝试着去做一些算法类的题了。递推,递归这块,还是很头疼,做的题少的缘故吧,总之看着别人的递推式,为什么这么样写,就是不明白,估计我还需要一段时间的磨练才能做到真正的掌握。做题的时候一定要静下心来冷静的分析问题,不能慌。

吉林省2017年冬令营DAY1