第11周

11.1 程序或算法的时间复杂度

时间复杂度是用在程序运行过程中,某种时间固定的操作需要被执行的次数和n的关系来度量的。在无序数列中查找某个数,复杂度是O(n)。

11.2 二分查找

 1 int BinarySearch(int a[], int size, int p)
 2 {
 3     int L = 0;
 4     int R = size-1;
 5     while(L <= R) {
 6         int mid = L+(R-L)/2;
 7         if(p == a[mid])
 8             return mid;
 9         else if(p > a[mid])
10             L = mid+1;
11         else
12             R = mid-1;
13     }
14 
15     return -1;
16 }
 1 int LowerBound(int a[], int size, int p)
 2 {
 3     int L = 0;
 4     int R = size-1;
 5     int LastPos = -1;
 6     while(L <= R) {
 7         int mid = L+(R-L)/2;
 8         if(a[mid] >= p)
 9             R = mid-1;
10         else {
11             LastPos = mid;
12             L = mid+1;
13         }
14     }
15 
16     return LastPos;
17 }

为了防止L+R可能过大溢出,int mid = L+(R-L)/2。

作业

1.矩形分割

Description:

平面上有一个大矩形,其左下角坐标(0,0),右上角坐标(R,R)。大矩形内部包含一些小矩形,小矩形都平行于坐标轴且互不重叠。所有矩形的顶点都是整点。要求画一根平行于y轴的直线x=k(k是整数) ,使得这些小矩形落在直线左边的面积必须大于等于落在右边的面积,且两边面积之差最小。并且,要使得大矩形在直线左边的的面积尽可能大。注意:若直线穿过一个小矩形,将会把它切成两个部分,分属左右两侧。

Input:

第一行是整数R,表示大矩形的右上角坐标是(R,R) (1 <= R <= 1,000,000)。接下来的一行是整数N,表示一共有N个小矩形(0 < N <= 10000)。

再接下来有N 行。每行有4个整数,L,T, W 和 H, 表示有一个小矩形的左上角坐标是(L,T),宽度是W,高度是H (0<=L,T <= R, 0

Output:输出整数n,表示答案应该是直线 x=n。 如果必要的话,x=R也可以是答案。

Sample Input:

1000
2
1 1 2 1
5 1 2 1

Sample Output:5

 1 #include <iostream>
 2 #include <ctime>
 3 #include <cmath>
 4 
 5 using namespace std;
 6 
 7 struct Rectangle {
 8     long long left, top, w, h;
 9 } a[10100];
10 
11 long long CountLeftSideArea(const Rectangle &r, long long x)
12 {
13     if(r.left >= x)
14         return 0;
15     if(r.left+r.w <= x)
16         return r.w*(long long)r.h;
17     return r.h*(x-r.left);
18 }
19 
20 int main()
21 {
22     int x, n, maxR;
23     cin >> maxR >> n;
24     for(int i = 0; i<n; ++i) {
25         cin >> a[i].left >> a[i].top >> a[i].w >> a[i].h;
26     }
27     int L = 0, R = maxR;
28     long long leftTotal, rightTotal, minDif;
29     while(L < R) {
30         x = (L+R)/2;
31         leftTotal = 0, rightTotal = 0;
32         for(int i=0; i<n; ++i) {
33             long long leftArea = CountLeftSideArea(a[i],x);
34             leftTotal += leftArea;
35             rightTotal += a[i].w*a[i].h-leftArea;
36         }
37         if(leftTotal-rightTotal >= 0) {
38             minDif = leftTotal-rightTotal;
39             R = x;
40         }
41         else
42             L = x+1;
43     }
44     R = maxR;
45     while(L < R) {
46         x = (L+R)/2;
47         if(x == L)
48             break;
49         leftTotal = 0;
50         rightTotal = 0;
51         for(int i=0; i<n; ++i) {
52             long long leftArea = CountLeftSideArea(a[i],x);
53             leftTotal += leftArea;
54             rightTotal += a[i].w*a[i].h-leftArea;
55         }
56         if(leftTotal-rightTotal > minDif)
57             R = x-1;
58         else
59             L = x;
60     }
61     leftTotal = 0, rightTotal = 0;
62     for(int i=0; i<n; ++i) {
63         long long leftArea = CountLeftSideArea(a[i],R);
64         leftTotal += leftArea;
65         rightTotal += a[i].w*a[i].h-leftArea;
66     }
67 
68     if(leftTotal-rightTotal == minDif)
69         cout << R << endl;
70     else
71         cout << L <<endl;
72 
73     return 0;
74 }

2.Pie

Description:

My birthday is coming up and traditionally I'm serving pie. Not just one pie, no, I have a number N of them, of various tastes and of various sizes. F of my friends are coming to my party and each of them gets a piece of pie. This should be one piece of one pie, not several small pieces since that looks messy. This piece can be one whole pie though.

My friends are very annoying and if one of them gets a bigger piece than the others, they start complaining. Therefore all of them should get equally sized (but not necessarily equally shaped) pieces, even if this leads to some pie getting spoiled (which is better than spoiling the party). Of course, I want a piece of pie for myself too, and that piece should also be of the same size.

What is the largest possible piece size all of us can get? All the pies are cylindrical in shape and they all have the same height 1, but the radii of the pies can be different.

Input:

One line with two integers N and F with 1 ≤ N, F ≤ 10 000: the number of pies and the number of friends.

One line with N integers ri with 1 ≤ ri ≤ 10 000: the radii of the pies.

Output:

Output one line with the largest possible volume V such that me and my friends can all get a pie piece of size V. The answer should be given as a floating point number rounded to 3 digits after decimal point.

Sample Input:

3 3
4 3 3

Sample Output:25.133

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <iomanip>
 4 #include <cmath>
 5 
 6 using namespace std;
 7 
 8 const double PI = acos(-1.0);
 9 const double eps = 1e-6;
10 
11 int N, F;
12 int r[10010];
13 
14 bool Valid(double V)
15 {
16     if(V < eps)
17         return true;
18     int total = 0;
19     for(int i=0; i<N; ++i) {
20         double n = r[i]*r[i]/V;
21         total += n;
22         if(total >= F)
23             return true;
24     }
25 
26     return false;
27 }
28 
29 int main()
30 {
31     cin >> N >> F;
32     ++F;
33     double maxV = 0;
34     for(int i=0; i<N; ++i) {
35         cin >> r[i];
36         maxV = max(maxV, (double)r[i]*r[i]);
37     }
38     double L = 0, R = maxV;
39     while(R-L > eps) {
40         double midV = L+(R-L)/2;
41         if(Valid(midV))
42             L = midV;
43         else
44             R = midV;
45     }
46 
47     cout << fixed << setprecision(3) << PI * L;
48 
49     return 0;
50 }

3.Monthly Expense

Description:

Farmer John is an astounding accounting wizard and has realized he might run out of money to run the farm. He has already calculated and recorded the exact amount of money (1 ≤ moneyi ≤ 10,000) that he will need to spend each day over the next N (1 ≤ N ≤ 100,000) days.

FJ wants to create a budget for a sequential set of exactly M (1 ≤ M ≤ N) fiscal periods called "fajomonths". Each of these fajomonths contains a set of 1 or more consecutive days. Every day is contained in exactly one fajomonth.

FJ's goal is to arrange the fajomonths so as to minimize the expenses of the fajomonth with the highest spending and thus determine his monthly spending limit.

Input:Line 1: Two space-separated integers: N and M, Lines 2..N+1: Line i+1 contains the number of dollars Farmer John spends on the ith day

Output:Line 1: The smallest possible monthly limit Farmer John can afford to live with.

Sample Input:

7 5
100
400
300
100
500
101
400

Sample Output:500

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <iomanip>
 4 #include <cmath>
 5 
 6 using namespace std;
 7 
 8 int N, M;
 9 int cost[100100];
10 
11 bool Valid(int c)
12 {
13     int m = 1;
14     int curCost = 0;
15     for(int i=0; i<N; ++i) {
16         if(cost[i] > c)
17             return false;
18         if(curCost+cost[i] > c) {
19             curCost = cost[i];
20             ++m;
21             if( m > M )
22                 return false;
23         }
24         else
25             curCost += cost[i];
26     }
27 
28     return true;
29 }
30 
31 int main()
32 {
33     cin >> N >> M;
34     int L = 1 << 30, R = 0;
35     for(int i=0; i<N; ++i) {
36         cin >> cost[i];
37         L = min(L, cost[i]);
38         R += cost[i];
39     }
40 
41     int lastValid = 0;
42     while(L <= R) {
43         int mid = L+(R-L)/2;
44         if(Valid(mid)) {
45             lastValid = mid;
46             R = mid-1;
47         }
48         else
49             L = mid +1;
50     }
51 
52     cout << lastValid ;
53 
54     return 0;
55 }

4.River Hopscotch

Description:

Every year the cows hold an event featuring a peculiar version of hopscotch that involves carefully jumping from rock to rock in a river. The excitement takes place on a long, straight river with a rock at the start and another rock at the end, L units away from the start (1 ≤ L≤ 1,000,000,000). Along the river between the starting and ending rocks, N (0 ≤ N ≤ 50,000) more rocks appear, each at an integral distance Di from the start (0 < Di < L).

To play the game, each cow in turn starts at the starting rock and tries to reach the finish at the ending rock, jumping only from rock to rock. Of course, less agile cows never make it to the final rock, ending up instead in the river.

Farmer John is proud of his cows and watches this event each year. But as time goes by, he tires of watching the timid cows of the other farmers limp across the short distances between rocks placed too closely together. He plans to remove several rocks in order to increase the shortest distance a cow will have to jump to reach the end. He knows he cannot remove the starting and ending rocks, but he calculates that he has enough resources to remove up to M rocks (0 ≤ M ≤ N).

FJ wants to know exactly how much he can increase the shortest distance *before* he starts removing the rocks. Help Farmer John determine the greatest possible shortest distance a cow has to jump after removing the optimal set of M rocks.

Input:

Line 1: Three space-separated integers: L, N, and M 

Lines 2..N+1: Each line contains a single integer indicating how far some rock is away from the starting rock. No two rocks share the same position.

Output:

Line 1: A single integer that is the maximum of the shortest distance a cow has to jump after removing M rocks

Sample Input:

25 5 2
2
11
14
17
21

Sample Output:4

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <iomanip>
 4 #include <cmath>
 5 
 6 using namespace std;
 7 
 8 int L, N, M;
 9 int D[50010];
10 
11 bool Valid(int d)
12 {
13     int removed = 0;
14     int last = 0;
15     for(int i=0; i<N; ++i) {
16         if(D[i]-last < d) {
17             ++removed;
18         if(removed > M)
19             return false;
20         }
21         else
22             last = D[i];
23     }
24     if(L-last < d)
25         ++removed;
26     if(removed > M)
27         return false;
28         
29     return true;
30 }
31 
32 int main()
33 {
34     cin >> L >> N >> M;
35     int e, last = 0, s = 1000000100;
36     for(int i=0; i<N; ++i) {
37         cin >> D[i];
38         s = min(s, D[i]-last);
39         last = D[i];
40     }
41 
42     s = min(s, L-D[N-1]);
43     e = L;
44     int lastValid = 0;
45     while(s <= e) {
46         int mid = s+(e-s)/2;
47         if(Valid(mid)) {
48             lastValid = mid;
49             s = mid+1;
50         }
51         else
52             e = mid - 1;
53     }
54 
55     cout << lastValid;
56     
57     return 0;
58 }

5.Aggressive cows

Description:

Farmer John has built a new long barn, with N (2 <= N <= 100,000) stalls. The stalls are located along a straight line at positions x1,...,xN (0 <= xi <= 1,000,000,000).

His C (2 <= C <= N) cows don't like this barn layout and become aggressive towards each other once put into a stall. To prevent the cows from hurting each other, FJ want to assign the cows to the stalls, such that the minimum distance between any two of them is as large as possible. What is the largest minimum distance?

Input:* Line 1: Two space-separated integers: N and C  * Lines 2..N+1: Line i+1 contains an integer stall location, xi

Output:* Line 1: One integer: the largest minimum distance

Sample Input:

5 3
1
2
8
4
9

Sample Output:3

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <iomanip>
 4 #include <cmath>
 5 #include <cstdio>
 6 
 7 using namespace std;
 8 
 9 int N, C;
10 int x[100010];
11 
12 bool Valid(int d)
13 {
14     int last = x[0];
15     int settled = 1;
16     for(int i=1; i<N; ++i) {
17         if(x[i]-last >= d) {
18             ++settled;
19             last = x[i];
20             if(settled >= C)
21                 return true;
22         }
23     }
24 
25     return false;
26 }
27 
28 int main()
29 {
30     scanf("%d %d", &N, &C);
31     for(int i=0; i<N; ++i)
32     scanf("%d", &x[i]);
33     
34     sort(x, x+N);
35     int L = 1;
36     int R = x[N-1]/C+1;
37     int lastValid = 0;
38     while(L <= R) {
39         int mid = L+(R-L)/2;
40         if(Valid(mid)) {
41             lastValid = mid;
42             L = mid+1;
43         }
44         else
45             R = mid -1;
46     }
47     
48     printf("%d
", lastValid);
49     
50     return 0;
51 }
原文地址:https://www.cnblogs.com/VincentValentine/p/5678392.html