CF#509 Div2

A.Heist

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 using namespace std;
 5 const int N=1010;
 6 int n; int a[N];
 7 int main() {
 8     scanf("%d",&n);
 9     for (int i=1;i<=n;i++)
10         scanf("%d",&a[i]);
11     sort(a+1,a+1+n);
12     printf("%d\n",a[n]-a[1]+1-n);
13     return 0;
14 }
View Code

 

B.Buying a TV Set

 

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 typedef long long ll;
 5 ll gcd(ll x,ll y) {
 6     if (!y) return x;
 7     return gcd(y,x%y);
 8 }
 9 int main() {
10     ll a,b,x,y;
11     scanf("%I64d%I64d",&a,&b);
12     scanf("%I64d%I64d",&x,&y);
13     ll t=gcd(x,y);
14     x/=t,y/=t;
15     ll ans=min(a/x,b/y);
16     printf("%I64d\n",ans);
17     return 0;
18 }
View Code

 

C.Coffee Break

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <set>
 5 using namespace std;
 6 const int N=200010;
 7 int n,m,d,ans,date[N];
 8 struct data {
 9     int id,val;
10     data(){}
11     data(int I,int V):id(I),val(V){}
12     bool operator < (const data &A) const {
13         return val<A.val;
14     }
15 };
16 set<data> S;
17 set<data>::iterator it;
18 int main() {
19     scanf("%d%d%d",&n,&m,&d);
20     for (int x,i=1;i<=n;i++) {
21         scanf("%d",&x);
22         S.insert(data(i,x));
23     }
24     data now(0,m);
25     for (int i=1;i<=n;i++) {
26         it=S.upper_bound(now);
27         if (it==S.end())
28             it=S.begin(),ans++;
29         now.val=it->val+d;
30         date[it->id]=ans;
31         S.erase(it);
32     }
33     printf("%d\n",ans);
34     for (int i=1;i<=n;i++) {
35         if (i==n) printf("%d\n",date[i]);
36         else printf("%d ",date[i]);
37     }
38     return 0;
39 }
View Code

 

D.Glider

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 using namespace std;
 5 const int N=200010;
 6 int n,h,ans;
 7 int a[N],c[N];
 8 struct data {
 9     int l,r;
10     data(){}
11     data(int L,int R):l(L),r(R){}
12     bool operator < (const data &A) const {
13         return l<A.l;
14     }
15 }q[N];
16 int main() {
17     scanf("%d%d",&n,&h);
18     for (int l,r,i=1;i<=n;i++) {
19         scanf("%d%d",&l,&r);
20         q[i]=data(l,r);
21     }
22     sort(q+1,q+1+n);
23     for (int i=1;i<=n;i++) {
24         a[i]=q[i].r-q[i].l;
25         c[i]=q[i].l-q[i-1].r;
26     }
27     int ed=0,cost=0,now;
28     for (int st=1;st<=n;st++) {
29         if (ed<st)
30             ed++,now=a[ed];
31         while(ed<n&&cost+c[ed+1]<h)
32             ed++,cost+=c[ed],now+=a[ed];
33         ans=max(ans,now);
34         now-=a[st];
35         if (st<ed) cost-=c[st+1];
36     }
37     printf("%d\n",ans+h);
38     return 0;
39 }
View Code

 

E.Tree Reconstruction

题目大意:有一棵$n$个点的树,给出$n-1$个数对,表示断了某条边之后剩余俩个连通块的最大节点编号,让你构造出一颗合法的树。

做法:观察发现一定有数对中一定有$n$,统计另外一个数的出现次数,我的构造方法构造若干条链,对于出现了$k$次的数可由$k-1$个比它小的数作为祖先节点,这样可以保证若不满足该条件,则一定不可能。

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 using namespace std;
 5 const int N=1010;
 6 int n,top;
 7 int cnt[N],tmp[N],fa[N];
 8 int main() {
 9     scanf("%d",&n);
10     for (int a,b,i=1;i<n;i++) {
11         scanf("%d%d",&a,&b);
12         if (a>b) swap(a,b);
13         if (b!=n) {
14             printf("NO\n");
15             return 0;
16         }
17         cnt[a]++;
18     }
19     for (int i=1;i<n;i++) {
20         if (!cnt[i]) tmp[++top]=i;
21         else {
22             int x=cnt[i]-1;
23             if (top<x) {
24                 printf("NO\n");
25                 return 0;
26             }
27             else {
28                 int last=i;
29                 for (int t,j=1;j<=x;j++)
30                     t=tmp[top--],fa[last]=t,last=t;
31                 fa[last]=n;
32             }
33         }
34     }
35     printf("YES\n");
36     for (int i=1;i<n;i++)
37         printf("%d %d\n",i,fa[i]);
38     return 0;
39 }
View Code

 

F.Ray in the tube

题目大意:给俩面平行的镜子,镜子上有一些检测器,你可以任选入射光方向和起始位置,问最多能射到几个检测器。

做法:第一反应是想办法去找等差数列,然后就对着这道题看了50min,太沙茶了……

正解是你考虑如果最后答案的公差是3,那么选择公差是1的数列也是可行的,所以只需要考虑的是公差为2的若干次幂的情况,因为会涉及到光来回照射的问题。

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <map>
 5 using namespace std;
 6 const int N=100010;
 7 int n,m,y;
 8 int a[N],b[N];
 9 map<int,int> M;
10 map<int,int>::iterator it;
11 int solve(int d) {
12     int dd=d*2,res=0;
13     M.clear();
14     for (int i=1;i<=n;i++)
15         M[a[i]%dd]++;
16     for (int i=1;i<=m;i++)
17         M[(b[i]+d)%dd]++;
18     for (it=M.begin();it!=M.end();it++)
19         res=max(res,it->second);
20     return res;
21 }
22 int main() {
23     scanf("%d%d",&n,&y);
24     for (int i=1;i<=n;i++)
25         scanf("%d",&a[i]);
26     scanf("%d%d",&m,&y);
27     for (int i=1;i<=m;i++)
28         scanf("%d",&b[i]);
29     int d=1,ans=2;
30     for (int i=1;i<=30;i++) {
31         ans=max(ans,solve(d));
32         d<<=1;
33     }
34     printf("%d\n",ans);
35     return 0;
36 }
View Code

 

posted @ 2018-09-17 10:53  2018szb  阅读(89)  评论(0)    收藏  举报