码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #352 (Div. 2) ABCD

时间:2016-05-13 08:29:00      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:

Problems
技术分享
 
 
#Name  
A
standard input/output
1 s, 256 MB
技术分享 技术分享 技术分享 x3197
B
standard input/output
2 s, 256 MB
技术分享 技术分享 技术分享 x2870
C
standard input/output
2 s, 256 MB
技术分享 技术分享 技术分享 x664
D
standard input/output
1 s, 256 MB
技术分享 技术分享 技术分享 x248
E
standard input/output
2 s, 256 MB
技术分享 技术分享 技术分享 x2

 

A Summer Camp

题意:有个 "123456789101112131415..."这样规律的字符串,求其中第n个字符是什么。 (1 ≤ n ≤ 1000) 

题解:暴力找,n只有1000,来个循环从1开始,整数分解,啪啪啪。

代码:

技术分享
 1 //#pragma comment(linker, "/STACK:102400000,102400000")
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<cmath>
 8 #include<map>
 9 #include<set>
10 #include<stack>
11 #include<queue>
12 using namespace std;
13 #define MZ(array) memset(array, 0, sizeof(array))
14 #define MF1(array) memset(array, -1, sizeof(array))
15 #define MINF(array) memset(array, 0x3f, sizeof(array))
16 #define REP(i,n) for(i=0;i<(n);i++)
17 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
18 #define FORD(i,x,y) for(i=(x);i>=(y);i--)
19 #define RD(x) scanf("%d",&x)
20 #define RD2(x,y) scanf("%d%d",&x,&y)
21 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
22 #define WN(x) printf("%d\n",x);
23 #define RE  freopen("D.in","r",stdin)
24 #define WE  freopen("huzhi.txt","w",stdout)
25 #define MP make_pair
26 #define PB push_back
27 #define PF push_front
28 #define PPF pop_front
29 #define PPB pop_back
30 typedef long long LL;
31 typedef unsigned long long ULL;
32 
33 const double PI=acos(-1.0);
34 const double EPS=1e-10;
35 
36 int farm(int n){
37     int i;
38     for(i=1; true; i++){
39         int j=i,k=0;
40         while(j){
41             j/=10;
42             k++;
43         }
44         if(n>k)n-=k;
45         else{
46             if(n==k)return i%10;
47             j=i;
48             int k2=0;
49 //            printf("%d!",j);
50             while(j){
51                 j/=10;
52                 k2++;
53                 if(k-k2==n)return j%10;
54             }
55         }
56     }
57 }
58 
59 int main(){
60     int n;
61     RD(n);
62     WN(farm(n));
63     return 0;
64 }
View Code

 

B. Different is Good

题意:给出一个小写字母字符串,可以对其中某个位置修改,要求以最少的修改次数,使其所有子串不同,输出修改次数,无解输出-1。

题解:

说是子串不同,其实单个字母就算一个子串,必须使所有字母不同。那超过26的就直接不行,不超过26的,统计各个字母的出现次数。

统计各个字母溢出字数和sum(对有出现的字母,每个字母出现次数-1,加和),统计没有出现的字母的个数last,last大于等于sum就输出sum,否则输出-1。

 

C. Recycling Bottles

题意:两个人捡垃圾,给出两个人的坐标、垃圾桶坐标、各个垃圾坐标,人有两种选择,可以【不动】,也可以【选一个垃圾,跑去垃圾坐标再跑去垃圾桶坐标】。要捡完所有垃圾,让两个人的行走距离的和最小,输出距离最小值。

 

题解:主要看第一次捡垃圾,因为之后都是【从垃圾桶走到垃圾,再走回垃圾桶】,所以主要看第一次【从初始坐标走到垃圾】这个能节省多少距离。

这个节省的是【从垃圾桶走到这个垃圾】的时间。

定义Gain = dis(垃圾,垃圾桶) - dis(人,垃圾),Gain越大效果越好,Gain为负数就是反效果。

首先分别对两个人找到他们Gain最高的垃圾和第二高的垃圾,因为他们可能选到同一个垃圾,所以找个第二高的备用。

所以两个人如果有一个Gain为负数,那就只用另一个人捡就行了。两个都为负数,就选个负得少一点的捡。

注意处理选到同一个垃圾的情况,我是分了5种方式,分别是

1.都捡最碉的

2.A捡A的最碉的,B捡B的第二碉的

3.B捡B的最碉的,A捡A的第二碉的

4.A捡最碉,B不捡

5.B捡最碉,B不捡

其中如果两个人选的是一个,就不考虑这个方式。对比各种方式Gain的大小,选最大的,稳。

代码:

技术分享
  1 //#pragma comment(linker, "/STACK:102400000,102400000")
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<cstring>
  6 #include<algorithm>
  7 #include<cmath>
  8 #include<map>
  9 #include<set>
 10 #include<stack>
 11 #include<queue>
 12 using namespace std;
 13 #define MZ(array) memset(array, 0, sizeof(array))
 14 #define MF1(array) memset(array, -1, sizeof(array))
 15 #define MINF(array) memset(array, 0x3f, sizeof(array))
 16 #define REP(i,n) for(i=0;i<(n);i++)
 17 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
 18 #define FORD(i,x,y) for(i=(x);i>=(y);i--)
 19 #define RD(x) scanf("%d",&x)
 20 #define RD2(x,y) scanf("%d%d",&x,&y)
 21 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
 22 #define WN(x) printf("%d\n",x);
 23 #define RE  freopen("D.in","r",stdin)
 24 #define WE  freopen("huzhi.txt","w",stdout)
 25 #define MP make_pair
 26 #define PB push_back
 27 #define PF push_front
 28 #define PPF pop_front
 29 #define PPB pop_back
 30 typedef long long LL;
 31 typedef unsigned long long ULL;
 32 
 33 const double PI=acos(-1.0);
 34 const double EPS=1e-10;
 35 const double MA=1e10*100;
 36 
 37 const int MAXN=111111;
 38 int n;
 39 int ax,ay,bx,by,cx,cy;
 40 int X[MAXN],Y[MAXN];
 41 
 42 double dis(int x,int y,int x2,int y2) {
 43     LL xx=x-x2;
 44     LL yy=y-y2;
 45     return sqrt(xx*xx+yy*yy);
 46 }
 47 
 48 double judge(int x,int y,int no) {
 49     if(no==-1)return MA;
 50     return dis(X[no],Y[no],cx,cy) - dis(x,y,X[no],Y[no]);
 51 }
 52 
 53 int findNearest(int x,int y,int &no2) {
 54     int no;
 55     double nd, nd2;
 56     no=0;
 57     no2=-1;
 58     nd=judge(x,y,no);
 59     nd2=MA;
 60     for(int i=1; i<n; i++) {
 61         double d=judge(x,y,i);
 62         if(d>nd) {
 63             no2=no;
 64             nd2=nd;
 65             no=i;
 66             nd=d;
 67         } else if(no2==-1 || d>nd2) {
 68             no2=i;
 69             nd2=d;
 70         }
 71     }
 72     return no;
 73 }
 74 
 75 bool ganked[MAXN];
 76 
 77 double farm() {
 78     MZ(ganked);
 79     int p[2],pp[2];
 80     double d[2],dd[2];
 81     p[0]=findNearest(ax,ay,pp[0]);
 82     p[1]=findNearest(bx,by,pp[1]);
 83     int no1[5]={p[0],   p[0],   pp[0],  p[0],   -1};
 84     int no2[5]={p[1],   pp[1],  p[1],   -1,     p[1]};
 85     int choose=-1;
 86     double gain;
 87     int i;
 88     REP(i,5){
 89         if(no1[i]==no2[i])continue;
 90         double g = 0.0;
 91         if(no1[i]!=-1) g+=judge(ax,ay,no1[i]);
 92         if(no2[i]!=-1) g+=judge(bx,by,no2[i]);
 93         if(choose==-1 || g>gain){
 94             choose = i;
 95             gain = g;
 96         }
 97     }
 98     bool bad[2]= {0};
 99     int q[2] = {no1[choose],no2[choose]};
100     if(no1[choose]==-1)bad[0]=1;
101     if(no2[choose]==-1)bad[1]=1;
102 //    cout<<q[0]<<‘,‘<<q[1]<<endl;
103     double re=0.0;
104     int onex[2]={ax,bx};
105     int oney[2]={ay,by};
106     REP(i,2) if(!bad[i]) {
107         re += dis(onex[i],oney[i],X[q[i]],Y[q[i]]);
108         ganked[q[i]]=1;
109     }
110 //    cout<<re<<endl;
111     REP(i,n) {
112         if(!ganked[i])re += dis(cx,cy,X[i],Y[i])*2;
113         else re+= dis(cx,cy,X[i],Y[i]);
114     }
115     return re;
116 }
117 
118 int main() {
119     int i;
120     scanf("%d%d%d%d%d%d",&ax,&ay,&bx,&by,&cx,&cy);
121     RD(n);
122     REP(i,n)RD2(X[i],Y[i]);
123     printf("%.10f\n",farm());
124     return 0;
125 }
View Code

 

D
standard input/output
1 s, 256 MB
技术分享 技术分享 技术分享 x252

D. Robin Hood

题意:罗宾汉劫富济贫,每天偷最有钱的人一块钱,给最穷的人。有多种选择的话随机偷。给出各个人初始钱数,罗宾汉偷钱天数,输出最后最有钱的人和最穷的人的钱数差。

人数n,天数k (1 ≤ n ≤ 500 000, 0 ≤ k ≤ 10^9)

题解:

偷10的9次方天,暴力一天一天偷肯定不行,要想办法一下计算很多天的偷。

我们可以用map来找最穷最有钱的人。map<int,int>,第一个int代表钱数,第二个int代表这个钱数的人数。就叫这个map叫S好了。

每次找到最有钱的人的钱数r,最没钱的人钱数l,一次我们可以帮x个人每个人偷e块钱,操作如下:

1 S[l]-=x;
2 S[r]-=x;
3 如果S[l]或者S[r]为0,就把它从S里删掉。
4 S[l+e]+=x;
5 S[r-e]+=x;

这个简单,关键是确定每次的人数x和钱数e。

1.不能偷多,我们不能让最有钱的人们被偷得比第二有钱的人们穷,也不能让最穷的人们比第二穷的人们有钱。所以

e <= min (最有钱的人们的钱数 - 第二有钱人们的钱数  ,  第二穷的人们的钱数 - 最穷的人们的钱数)

2.确定人数x,设最穷的人的人数ln,最有钱的人的人数rn,则

x <= min(ln, rn)

3.还要看罗宾汉剩余的天数k,量力而行

e <= k/x

(把x个人每人偷e块钱,需要e*x天,天数要k>=e*x)

如果因为此限制,e必须为0,则说明罗宾汉无力缩小贫富差距了,直接输出当前的贫富差距。

4.如果ln和rn不同,偷完后会剩下abs(rn-ln)人,如果这时k不够了,无法把剩下的人改变e,岂不是贫富差距拉大,所以要 

1         maxX = max(ln, rn)
2         if(x != maxX){
3             e=min(k/maxX, e);
4             e=max(1,e);
5         }

也就是限制e,使得k足够,贫富差距不会拉大。

5.预先可以快速判断是否能将贫富差距缩到最小,也就是算一下钱平均值,然后对每个大于平均值的减去平均值,加和得到sum,也就是拉到平均值所需要的天数,如果罗宾汉天数k大于这个天数,则直接输出(sum%n==0 ? 0 : 1)

(不能整除的话说明最后贫富差距不会缩小到0,最小是1)

 

大概就是上面这些条件吧,就可以快速地每次把x个人每人偷e块钱,最后他们会越来越多聚集到同一钱数,时间复杂度我也不会算,好像不是很大。

代码:

技术分享
  1 //#pragma comment(linker, "/STACK:102400000,102400000")
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<cstring>
  6 #include<algorithm>
  7 #include<cmath>
  8 #include<map>
  9 #include<set>
 10 #include<stack>
 11 #include<queue>
 12 using namespace std;
 13 #define MZ(array) memset(array, 0, sizeof(array))
 14 #define MF1(array) memset(array, -1, sizeof(array))
 15 #define MINF(array) memset(array, 0x3f, sizeof(array))
 16 #define REP(i,n) for(i=0;i<(n);i++)
 17 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
 18 #define FORD(i,x,y) for(i=(x);i>=(y);i--)
 19 #define RD(x) scanf("%d",&x)
 20 #define RD2(x,y) scanf("%d%d",&x,&y)
 21 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
 22 #define WN(x) printf("%d\n",x);
 23 #define RE  freopen("D.in","r",stdin)
 24 #define WE  freopen("huzhi.txt","w",stdout)
 25 #define MP make_pair
 26 #define PB push_back
 27 #define PF push_front
 28 #define PPF pop_front
 29 #define PPB pop_back
 30 typedef long long LL;
 31 typedef unsigned long long ULL;
 32 
 33 const double PI=acos(-1.0);
 34 const double EPS=1e-10;
 35 
 36 const int MAXN=511111;
 37 int n,k;
 38 int a[MAXN];
 39 
 40 int farm() {
 41     int i;
 42     LL sum=0;
 43     REP(i,n)sum+=a[i];
 44     double avg = 1.0*sum/n;
 45     int need=0;
 46     REP(i,n) {
 47         if(a[i]>avg)need+=ceil(a[i]-avg);
 48         if(need>k)break;
 49     }
 50     if(need<=k)return sum%n==0?0:1;
 51     if(n==1)return 0;
 52     map<int,int> s;
 53     REP(i,n)s[a[i]]++;
 54     map<int,int>::iterator q,w,q2,w2;
 55     while(k) {
 56         q = s.begin();
 57         w = s.end();
 58         w--;
 59         int l =  q->first;
 60         int r = w->first;
 61         if(l==r)break;
 62         q2=q;
 63         w2=w;
 64         q2++;
 65         w2--;
 66         int e,man;
 67         e = min(q2->first - l, r - w2->first);
 68         man = min(q->second, w->second);
 69         e = min(k/man,e);
 70 //        printf("%d,%d,%d\n",e,k,man);
 71         if(e==0)break;
 72         int maxMan = max(q->second, w->second);
 73         if(man != maxMan){
 74             e=min(k/maxMan, e);
 75             e=max(1,e);
 76         }
 77         q->second-=man;
 78         w->second-=man;
 79         if(q->second==0)s.erase(q);
 80         if(w->second==0)s.erase(w);
 81         k-=e*man;
 82         r-=e;
 83         l+=e;
 84         s[r]+=man;
 85         s[l]+=man;
 86 
 87     }
 88     q = s.begin();
 89     w = s.end();
 90     w--;
 91     int l =  q->first;
 92     int r = w->first;
 93     return r-l;
 94 }
 95 
 96 int main() {
 97     int i;
 98     RD2(n,k);
 99     REP(i,n)RD(a[i]);
100     WN(farm());
101     return 0;
102 }
View Code

 

Codeforces Round #352 (Div. 2) ABCD

标签:

原文地址:http://www.cnblogs.com/yuiffy/p/5485377.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!