A

当前数量为x,前一天数量为x/2,以此类推
若x为奇数,则说明当前天要增加一个,否则可以转移到前一天。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<bits/stdc++.h>
using namespace std;

int main()
{
//freopen("test.txt","r",stdin);
int x;
while(scanf("%d",&x)==1)
{
if(x==1) puts("1");
else
{
int ans = 0;
while(x)
{
if(x&1) ++ans;
x/=2;
}
printf("%d\n",ans);
}
}
return 0;
}

B

按权值排序后配对即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include<bits/stdc++.h>
using namespace std;

const int maxn = 1000010;
int n;
bool vis[maxn];
int ans[810];
pair<int,int> a[maxn];

int main()
{
//freopen("test.txt","r",stdin);
while(scanf("%d",&n)==1)
{
int mx = 0;
n*=2;
memset(ans,0,sizeof ans);
memset(vis,0,sizeof vis);
for(int i=2;i<=n;++i)
{
for(int j=1;j<i;++j)
{
int t;
scanf("%d",&t);
a[t] = make_pair(j,i);
mx = max(mx,t);
vis[t] = 1;
}
}
for(int i=mx;i>0;--i)
{
if(!vis[i]) continue;
int u = a[i].first,v = a[i].second;
if(ans[u] || ans[v]) continue;
ans[u] = v;
ans[v] = u;
}
for(int i=1;i<=n;++i) printf("%d%c",ans[i],i==n?'\n':' ');
}
return 0;
}

C

给出(a,b),我们知道$a \le b$,$2kx = a-b \;or\; a+b = c$
$x = \frac{c}{2k} \le b$ 由于题目要求最小的x,我们二分k即可
可知$c = a+b$时解总是更优(k更大,x更小)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
const int INF = 0x3f3f3f3f;

int a,b;

double solve()
{
int l = 0,r = INF,res=1;
while(l <= r)
{
int m = (l+r)/2;
if((double)(a+b)/(2*m) >= (double)b)
{
l = m+1;
res = m;
}
else r = m-1;
}
return (double)(a+b)/(2*res);
}

int main()
{
//freopen("test.txt","r",stdin);
while(scanf("%d %d",&a,&b)==2)
{
if(a<b) puts("-1");
else
{
printf("%.12lf\n",solve());
}
}
return 0;
}

D

可以发现将这k次全部乘到一个数上总是更优,然后暴力一下就出来了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include<bits/stdc++.h>
using namespace std;

typedef long long LL;

const int maxn = 200010;
const double eps = 1e-7;
int n,k,x;
int a[maxn];
int bit[100],tmp[100];

int main()
{
//freopen("test.txt","r",stdin);
while(scanf("%d%d%d",&n,&k,&x)==3)
{
memset(bit,0,sizeof bit);
for(int i=0;i<n;++i) scanf("%d",a+i);
for(int i=0;i<n;++i)
{
int t = a[i],p=0;
while(t)
{
if(t&1) ++bit[p];
++p;
t>>=1;
}
}
LL ans = 0;
for(int i=0;i<32;++i) if(bit[i]) ans |= 1<<i;
for(int i=0;i<n;++i)
{
int t = a[i],p=0;
LL tt = (LL)t*(LL)(pow(x,k)+eps);
memcpy(tmp,bit,sizeof bit);
while(t)
{
if(t&1) --tmp[p];
++p;
t>>=1;
}
p = 0;
while(tt)
{
if(tt&1) ++tmp[p];
++p;
tt>>=1;
}
LL res = 0;
for(int i=0;i<64;++i) if(tmp[i]) res |= 1LL<<i;
// printf("%d\n",res);
ans = max(ans,res);
}
printf("%I64d\n",ans);
}
return 0;
}

E

三分,注意精度要取 1e-11 (1e-6/1e5)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
const double eps = 1e-11;
const int maxn = 200010;
double a[maxn],mn,mx;
int n;

double cal(double x)
{
double res = 0;
double cur = 0;
for(int i=0;i<n;++i)
{
cur = max(0.0,cur+a[i]+x);
res = max(cur,res);
}
cur = 0;
for(int i=0;i<n;++i)
{
cur = max(0.0,cur-(a[i]+x));
res = max(cur,res);
}
return res;
}

double solve()
{
double high = -mn,low = -mx;
int cnt = 0;
// for(int i=0;i<85;++i)
while(high-low>eps)
{
double mid = (high+low)/2;
double midmid = (mid+high)/2;
double cmid = cal(mid),cmidmid = cal(midmid);
if(cmid > cmidmid)
low = mid;
else
high = midmid;
}
// printf("%d\n",cnt);
return cal((low+high)/2);
}


int main()
{
//freopen("test.txt","r",stdin);
while(scanf("%d",&n)==1)
{
mx = -10001;
mn = 10000;
for(int i=0;i<n;++i)
{
scanf("%lf",a+i);
mx = max(a[i],mx);
mn = min(a[i],mn);
}
printf("%.12lf\n",solve());
}
return 0;
}