CSU1568-Shrine Maintenance

来源:互联网 发布:淘宝商城三星手机壳 编辑:程序博客网 时间:2024/06/07 08:34

Shrine Maintenance

        Time Limit: 2 Sec     Memory Limit: 128 Mb     Submitted: 140     Solved: 68     SpecialJudge

Description

A religious sect has holy sites with shrines placed around a circle of radius 1000. The circle is split into N equal length arcs and the endpoints are numbered in order, 1 through N. The first figure shows a circle where N is 12, with 12 gray tick marks like on a 12-hour analog clock. We can imagine the marks numbered, as on a clock, with 12 at the top. Each circle has one or more sacred numbers associated with it. The sacred numbers for the circle in the first figure are 2 and 3. A shrine, indicated by a black dot in the figure, is placed at each mark whose number is a multiple of at least one of the sacred numbers, so in this case the shrines are at positions 2, 3, 4, 6, 8, 9, 10, and 12.


When it comes time to inspect and repair the shrines at a given site, the area is closed and a team of workers simultaneously fan out from a maintenance shed, located in the center of the circle, so that each shrine is visited by at least one worker. Once all workers have returned to the shed, the site is reopened to the public. Because these sites are in great demand, it is important that they be closed as briefly as possible. In order to minimize this time, they must figure out how to apportion the shrines among the current number of workers, so the maximum distance traveled by any one worker is as small as possible. Figure 1 shows one choice for the optimal solution paths for 3 workers. The lower left path has darker lines, to indicate that it is one with the longest length, which in this case is approximately 3517.6. 
This sect has many circular sites with multiple shrines. The number of available workers at a site, W, the value of the number equal arcs, N, and the sacred numbers vary between sites. The sacred numbers are always divisors of N. Your job is to help figure out how much time is required for maintenance. Figures 2 and 3 show optimal solutions for other sites.

Input

The input consists of one or more data sets. Each data set is on a single line and consists entirely of positive integers. The first three entries are W, the number of workers, N, the number of equal arcs around the circle, and D, the number of sacred divisors of N. At the end come the D divisors of N. W is no more than the total number of shrines; N ≤ 8600, and D ≤ 6; each listed divisor of N is smaller than N.

A single zero, 0, will be placed on the last line to indicate the end of the input.

Output

The output is a single line for each dataset: the maximum distance a worker must travel with an optimal assignment of the shrines. This number is displayed so that it is rounded to one decimal place, and always shows that decimal place, even if it is 0. To ensure unique answers with double arithmetic, the datasets are chosen so that if your answer is anywhere within .005 of the exact minimum distance, then the answer rounded to one decimal place will be the same.

The first three sample datasets correspond to the three figures.

Caution: Be careful with your algorithm so it finishes rapidly.

Sample Input

3 12 2 2 37 70 3 14 10 352 84 3 3 4 144 35 2 7 53 20 2 5 43 6 1 14 6 1 11 6 1 18600 8600 3 1 10 1000

Sample Output

3517.62624.34987.73224.93488.43000.03000.07000.02000.0

Hint

Source


题意:将一个半径为1000的圆平分为n份,用有效点组成m个类三角形,有效点为给出的d个数字中任意一个数的倍数,问m个类三角形中周长最大值得最小值为多少

解题思路:二分+验证即可


#include <iostream>  #include <cstdio>  #include <cstring>  #include <string>  #include <algorithm>  #include <map>  #include <set>  #include <stack>  #include <queue>  #include <vector>  #include <bitset>  #include <functional>using namespace std;#define LL long long  const int INF = 0x3f3f3f3f;int n, m, d;int vis[100005], a[100005], cnt;double x[100005];int check(double k){for (int i = 0; i < cnt / 2; i++){int cnt = 1;double sum = 0;for (int j = i + 1; a[j] - a[i] < n; j++){if (sum + x[a[j] - a[j - 1]] <= k) sum += x[a[j] - a[j - 1]];else cnt++, sum = 0;}if (cnt <= m) return 1;}return 0;}int main(){while (~scanf("%d%d%d", &m, &n, &d) && m){memset(vis, 0, sizeof vis);cnt = 0;for (int i = 0; i < d; i++){int k;scanf("%d", &k);for (int j = k; j <= n; j += k) vis[j] = 1;}for (int i = 1; i <= n; i++){if (vis[i]) a[cnt++] = i, a[cnt++] = i + n;x[i] = 2000 * sin(acos(-1.0) * i / n);}sort(a, a + cnt);double l = 0, r = 2000 * acos(-1.0);while (r - l > 1e-8){double mid = (l + r) / 2;if (check(mid)) r = mid;else l = mid;}printf("%.1lf\n", l + 2000);}return 0;}

原创粉丝点击