2016_1_13

小兵的故事

(bin.cpp/c/pas)

Time limited = 1500ms

小兵休息时喜欢打打炉石和刀塔,然而这在伟大的计算机房是不怎么允许的。

已知伟大的计算机房有两个房门:前门和后门。

这两个门都有着高超的科技,可以设定一个参数tz

如果一个人会在T1时刻进来,那么就会在T1-t时刻把门打开,

但是如果下一个人在T2时刻进来:

1)如果该T2-T1<=2t,那么门会在T2+t时刻关上

2)否则,会先在T1+t时刻关上,T2-t时刻打开,T2+t时刻再关上。

 

如果两个门同时打开的时间超过d(一旦有任意一个门关上则重新计算),那么就会形成冷空气对流,小兵就会感觉到寒冷,高超的操作就会受到影响。

如果两个门开关的次数太多,就增加了被查房的风险。

 

小兵现在已经预测出午休时间两个门分别会在哪些时刻进来人,现在问题是如何设定前门和后门的两个参数:t1t2(必须是>=1的整数)使得:

1、两个门同时打开的时间不超过d(一旦有任意一个门关上则重新计算)

2、两个门的打开的次数之和尽可能的小

 

输入描述:

第一行三个整数NMd

第二行N个整数,p1<p2<…<pN,表示前门会在哪些时刻进来人

第三行M个整数,q1<q2<…<qM表示后门会在哪些时刻进来人

d,p,q<=10^9

10% N,M<=50

30% N,M<=500

100% N,M<=5000

输出描述:

一个整数Ans表示两个门打开的次数之和。如果无解输出”No solution”不包括引号。

输入样例:

3 2 4

1 6 13

7 11

输出样例:

3

 

好久没写随笔了今天写一发。。这道题其实蛮水的但是我码第二题去了我真是蠢。

首先发现了ta,tb对应的单调性的关系,ta增加,tb只可能不变或者减少。考虑到ta,tb各最多有5000个,直接暴力就好了。

交的时候我T了一次是因为check的时候用的n^2,蠢哭了。稍微改一下扫一遍就好。

 

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstdlib>
 5 using namespace std;
 6 const int N = 5003;
 7 int ta[N],tb[N],lena,lenb;
 8 int a[N],b[N],m,n,d;
 9 int ans = 2000000000;
10 struct quiian {
11     int x,y;
12 }A[N],B[N];
13 inline int Calc(int x,int y,int c,int d) {
14     int S = min(x,c);
15     int T = max(y,d);
16     return y-x + d-c -(T-S);
17 }
18 int main() {
19     freopen("bin.in","r",stdin);
20     freopen("bin.out","w",stdout);
21     scanf("%d%d%d",&n,&m,&d);
22     for(int i = 1 ; i <= n ; ++i) {
23         scanf("%d",&a[i]);
24         if(i>=2) ta[++lena] = (a[i] - a[i-1] + 1)/2;
25     }
26     ta[++lena] = 1;
27     sort(ta+1,ta+1+lena);
28     for(int i = 1 ; i <= m ; ++i) {
29         scanf("%d",&b[i]);
30         if(i>=2) tb[++lenb] = (b[i] - b[i-1] + 1)/2;
31     }
32     tb[++lenb] = 1;
33     sort(tb+1,tb+1+lenb);
34     int last = lenb;
35     for(int i = 1 ; i <= lena ; ++i) {
36         int cnt = 0,t1 = 0;
37         cnt++;
38         A[++t1].x = a[1] - ta[i];
39         for(int j = 1 ; j < n ; ++j) {
40             if(a[j+1] - a[j] <= 2*ta[i]) continue;
41             A[t1].y = a[j] + ta[i];
42             A[++t1].x = a[j+1] - ta[i];
43             cnt++;
44         }
45         A[t1].y = a[n] + ta[i];
46         bool flag = true;
47         do {
48             int cnt2 = 0,t2 = 0;
49             flag = true;
50             cnt2++;
51             B[++t2].x = b[1] - tb[last];
52             for(int j = 1 ; j < m ; ++j) {
53                 if(b[j+1] - b[j] <= 2* tb[last]) continue;
54                 B[t2].y = b[j] + tb[last];
55                 B[++t2].x = b[j+1] - tb[last];
56                 cnt2++;
57             }
58             B[t2].y = b[m] + tb[last];
59             int stt = 1;
60             for(int i = 1 ; i <= t1 ; ++i) {
61                 if(A[i].y < B[stt].x) continue;
62                 while(B[stt].y < A[i].x && stt<=t2) stt++;
63                 if(stt>t2) break;
64                 for(int j = stt ; j <= t2 ; ++j) {
65                     if(B[j].x > A[i].y) break;
66                     int linshi = Calc(A[i].x,A[i].y,B[j].x,B[j].y);
67                     if(linshi > d) {
68                         flag = false; break;
69                     }
70                 }
71                 if(!flag) break;
72             }
73             if(!flag) last--;
74             else ans = min(ans,cnt + cnt2);
75             if(last==0) break;
76         }while(!flag);
77         if(last==0) break;
78     }
79     if(ans > n+m)printf("No solution");
80     else cout << ans << endl;
81 }
View Code

然后这道题最后时限改成了2.5秒。我最慢的点跑了1.93+呢,,写的有点丑

posted @ 2016-01-13 15:22  443singer  阅读(160)  评论(0编辑  收藏  举报