Test on 08/27/2016

1.切香肠

  (kusac.pas/c/cpp)

【问题描述】

    Jzyz的某次期中考试奖学金是由火腿肠企业赞助的,于是,奖学金变成了奖品,并且是N根长度完全相同的火腿肠。

本次考试一共M名同学获奖,学校决定,火腿肠全部平均分配,小x因为考试成绩很好,于是被选派为分火腿肠的人。

小x现在有一把很精确的刀,他可以一刀切掉火腿肠的任意需要的指定部分,小x现在想知道,如何用最少切的次数,完成火腿肠的分配。

比如,现在有2根火腿肠,有6个人获奖,那么,每根火腿肠需要切2刀,这样4刀就将火腿肠等分为6等份。

如果有3根火腿肠,4个人获奖,那么小x只需要把每根火腿肠切掉1/4,这样有3个人拿到每根的3/4,有一个人拿到3小块的1/4.这样最少3刀也能等分。

现在你需要帮助小x完成这个任务。

【输入】

两个整数N和M

【输出】

一个整数,最少切多少次可以平分。

【输入输出样例1】

kusac.in

kusac.out

2 6

4

 

【输入输出样例2】

kusac.in

kusac.out

3 4

3

 

【输入输出样例3】

kusac.in

kusac.out

6 2

0

 

【数据范围】

30%  1 ≤ N, M≤ 16 

100% 数据(1 ≤ N, M≤ 100)

其实到后来讲题解的时候我连最大公约数是什么都不知道,会算但是具体干嘛的不知道,这就很尴尬。

最大公约数最好用欧几里得算法。

将N根火腿肠放在一起,假设是一根的话,那么切M-1刀,就肯定得到了M根。

但是,如果要切这M-1刀中,恰好有k刀是N根火腿肠的分割处,那么就不用切了。那么恰好会有多少分割处是要切的呢?

就是M和N的最大公约数-1次,

所以 结论 就是 M-1-(gcd(M,N)-1)= M- gcd(M,N)

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 int gcd(int a,int b)
 5 {
 6     if(b==0)    return b;
 7     return (b,a%b);
 8 }
 9 int main()
10 {
11     freopen("kusac.in","r",stdin);
12     freopen("kusac.out","w",stdout);
13     int n,m;
14     cin>>n>>m;
15     if((n>m&&n%m==0)||n==0||m==0)    cout<<"0"<<endl;
16     else
17         cout<<m-gcd(n,m)<<endl;
18     fclose(stdin);
19     fclose(stdout);
20     return 0;
21 }

 

2.赛车

  (car.pas/c/cpp)

【问题描述】

    Jzyz的老师们要结伴出游了,并且他们到了一个很宽阔的赛车场,并且赛车场两边的风景是极好的,所以赛车不重要,看风景最重要。

    现在jzyz有N名老师要参加看风景赛车,编号为1..N,赛车场有M条(1<=M<=N)条车道,编号为i的老师自己的车速最大为Si(1<=Si<=10^6)。

    在经历很多次模拟驾驶之后,老师们为了避免碰撞,于是规定,每条车道上,如果某位老师前面有k个老师,那么这位老师的车速上限就会下降k*D个单位,也就是说第i个老师的开车的速度不会超过Si-k*D(0<=D<=5000),当然,如果这个数是负的,这个老师的速度将是0.当然只要遵循这个规则,老师们肯定就不会发生碰撞。

    但是,最后老师们才发现,赛车场有规定,在赛道上行驶的车辆速度不得低于L(1<=L<=10^6)。

    给定所有的数据,现在请你帮老师们计算一下,最多有多少个老师可以完成比赛,并欣赏到风景。

【输入】

         第一行四个整数N,M,D,L。

         接下来N行,每行一个整数,第i行为Si,表示第i位老师的车速上限。

【输出】

一个整数,最多有多少老师可以完成比赛。

【输入输出样例】

car.in

car.out

3 1 1 5
5
7
5

2

有3个老师,1个赛道,第一个和第二个老师可以参加比赛。

【数据范围】

   50%  保证N<=100;

   100%  N<=50000,其余如题目描述

首先先排序,这个属于自己的失误了,因为样例没有排序,所以我以为不用排序,然而考试中我是想到要排序的,然而停电了我就觉得不用排后来就失分辣。

为了让更多的老司机参加比赛必须以speed从小到大排序。

能参加就参加不参加就不参加。

用for循环人,每个赛道一个人,这样是最贪心的策略。

有一个神犇太赞,用一个 总数/赛道 的方法就可以求出老司机前面有多少人。

果然还是太蠢了啊。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 int n,m,d,l,a[50010];
 6 int ans=0;
 7 int main()
 8 {
 9     freopen("car.in","r",stdin);
10     freopen("car.out","w",stdout);
11     cin>>n>>m>>d>>l;
12     for(int i=1;i<=n;i++)
13         cin>>a[i];
14     sort(a+1,a+n+1);
15     for(int i=1;i<=n;i++)
16         if(a[i]-(ans/m)*d>=l)
17             ans++;
18     cout<<ans<<endl;
19     fclose(stdin);
20     fclose(stdout);
21     return 0;
22 }

 

 

3.排序

  (sort.pas/c/cpp)

【问题描述】

    小x在学习了各种排序算法后,决定自己设计一个排序算法。

    他设计的排序算法有两种操作:

1) 挑出某个数,将其放在序列的最前面;

2) 挑出某个数,将其放在序列的最后面;

现在小x想知道,在最优情况下,按上面的操作将n个数排序完毕,最少的操作次数是多少?

给定一个序列:{8,12,25,7,15,19}

只需要将7放在前面,25 放在后面,两个操作即可。

【输入】

第一行一个数N,表示有N个数需要排序。

       第二行N个整数,用空格隔开,表示要排序的N个数

 

【输出】

一个整数表示需要的操作次数。

【输入输出样例1】

sort.in

sort.out

6

8 12 25 7 15 19

2

 

 

 

【数据范围】

      对于30% 的数据 N≤50;

       对于60% 的数据 N≤1 000;

       对于100% 的数据 N≤100 000,且保证排序的每个数都不相同。

 

比如样例:

8 12 25 7 15 19

我们发现 8  12  15  19 是最长的,所以,不需要改变位置的是4个数,需要改变的是 6-4=2个。

所以,本题就是找到一个排完序后是连续的,且在原序列中下标也是递增的最长的序列。

这题看着题解我都懵逼。然而我并不会QwQ。

噗,原来这和题目一点关系都木有。

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 int n,ans=0,sum=1;
 5 struct ha
 6 {
 7     int s,id;
 8 }a[10010];
 9 bool cmp(ha a,ha b)
10 {
11     return (a.s<b.s);
12 }
13 int main()
14 {
15     cin>>n;
16     for(int i=1;i<=n;i++)
17     {    cin>>a[i].s;
18         a[i].id=i;
19     }
20     sort(a+1,a+n+1,cmp);
21     for(int i=1;i<n;i++)
22         if(a[i].id<a[i+1].id)
23         {    sum++;
24             if(sum>ans)    ans=sum;
25         }
26         else
27             sum=1;
28     cout<<n-ans<<endl;
29     return 0;
30 }

 

 

 

4.推销员

  (salenet.pas/c/cpp)

【问题描述】

    某商品推销员到某小区推销产品,产品推销除了商品质量好之外,还需要客户能影响和带动身边信赖他的人也购买,如果A购买了产品,那么信赖A的B就有可能也购买,那么信赖B的C就也可能成为潜在客户。依据这种信赖关系,就可能构成一个庞大的潜在客户网。

聪明的推销员经过细心调查整理了这个小区里N个人的信赖关系,并且用1~N给这N个人编号。另外,这N个人中有P个潜在客户可能会被推销员直接说服购买产品,细心的推销员还估算了说服每个人具体需要花费的时间,那么请你帮推销员计算一下他最少需要花费多长时间来建立起这N个人的潜在客户网?

如果不能把这N个人全部纳入潜在客户网,输出不能被纳入网络的人的编号。注意,信赖关系不一定是相互的啊!

【输入】

输入文件第一行只有一个整数n(n<=3000)。

第二行是整数p。表示能被说服的人数,1≤p≤n。

 接下来的p行,每行有两个整数,第一个数是一个能被说服的人的编号,第二个数表示他被说服需要花费的时间。这个数不超过20000个时间单位。

紧跟着一行只有一个整数r,1≤r≤8000。然后r行,每行两个正整数,表示数对(A, B),B信赖A。

【输出】

如果可以把N个人全部纳入潜在客户网,第一行输出YES,并在第二行输出所需要花费的最少说服时间。否则输出NO,并在第二行输出不能纳入网络的人编号中,编号最小的。

【输入输出样例1】

salenet.in

salenet.out

3  

2  

1 10

2 100

2

1 3

2 3

YES

110

 

 

 

【输入输出样例2】

salenet.in

salenet.out

4         

2         

1 100

4 200

2

1 2

3 4

 

NO

3

 

 

【数据范围】

  对于30%的输入数据有n<=10。

对于100%的输入数据有n<=3000。

这题是什么,唔 图论。嗯赶在考试之前把图论刷刷。

对于所有依赖关系(A,B)建立有向边A->B,先BFS判断是否有解。

如果有解,就缩环成为DAG,直接取没有入度的点。

然而在考试中知道是图我连看都没看。

原来全加起来可以骗40分。QAQ

总之来说考得不好,不过别人也都没考好

嗯..122/400,最高244

大概最后一题骗40,第一题第二题200,第三题当时真心想不到。

但是也是很高的名次,嗯对就这样。

 

 

No matter how you feel, get up , dress up , show up ,and never give up.
原文地址:https://www.cnblogs.com/Kaike/p/5839681.html