Codeforces Round #262 (Div. 2) 二分+贪心

题目链接

Little Dima and Equation

题意:给a, b,c 给一个公式,s(x)为x的各个位上的数字和,求有多少个x.

分析:直接枚举x肯定超时,会发现s(x)范围只有只有1-81,所以枚举一下就行。

在做题的时候,用了pow()错了3次,反正以后不用pow了,还是手写吧。会有误差。pow返回的是double型的。

昨天在b题耽误了好多时间,先是提交错第一组,然后又被人cha了。注意在x在1-10^9之间。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <vector>
 4 #include <cmath>
 5 #include <cstring>
 6 #include <cstdlib>
 7 #include <algorithm>
 8 #define LL __int64
 9 const int maxn = 1000+10;
10 using namespace std;
11 LL y[maxn];
12 int check(LL x)
13 {
14     int sum = 0;
15     while(x)
16     {
17         sum += x%10;
18         x /= 10;
19     }
20     return sum;
21 }
22 LL pow_m(int a, int b)
23 {
24     LL ret = 1;
25     for(int i = 1; i <= b; i++)
26         ret *= a;
27     return ret;
28 }
29 int main()
30 {
31     LL a, b, c, i;
32     int cnt;
33     LL tmp;
34     while(~scanf("%I64d%I64d%I64d", &a, &b, &c))
35     {
36         cnt = 0;
37         memset(y, 0, sizeof(y));
38         for(i = 1; i <= 81; i++)
39         {
40             //tmp = (LL)pow(i, a);  //用这个我的程序跑的数据对,但是测试数据不对
41             tmp = pow_m(i, a);
42             tmp = (LL)tmp*b + (LL)c;
43             if(check(tmp)==i)
44                 {
45                     if(tmp > 0 && tmp < 1000000000)
46                     y[cnt++] = tmp;
47                 }
48         }
49         sort(y, y+cnt);
50         printf("%d
", cnt);
51         for(i = 0; i < cnt; i++)
52         {
53             if(i==cnt-1)
54                 printf("%I64d
", y[i]);
55             else
56                 printf("%I64d ", y[i]);
57         }
58     }
59     return 0;
60 }

Present

题意:给一串n个数字,可以对连续的w个数字增加1,共增加m次,问增加完以后最小的数字是多少,让求所有方法里最小数字的最大值。

分析:

对结果二分就行了,即二分最小的值,然后都符合的话,往上加一个。

这个题和poj计划上的那两个二分题差不多,比赛的时候因为前面的b题实在是脑残了,做这个题没时间了,当时思路也不是很好,没写出来。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <vector>
 4 #include <cmath>
 5 #include <cstring>
 6 #include <cstdlib>
 7 #include <algorithm>
 8 #define LL __int64
 9 const int maxn = 100000+10;
10 using namespace std;
11 int a[maxn], f[maxn];
12 
13 int main()
14 {
15     int i, n, m, w, y;
16     int low, mid, hig, tmp, ans, t2;
17     while(~scanf("%d%d%d", &n, &m, &w))
18     {
19         for(i = 0; i < n; i++)
20         {
21             scanf("%d", &a[i]);
22             if(i==0) low = a[i];
23             else if(a[i]<low)
24             low = a[i];
25         }
26         hig = m+low; 
27         while(hig>=low)
28         {
29             y = m;
30             tmp = 0;
31             memset(f, 0, sizeof(f));
32             mid = (low+hig)/2;
33             for(i = 0; i < n; i++)
34             {
35                 t2 = a[i];
36                 tmp -= f[i]; //先减去已经在增加范围之外的。
37                 t2 += tmp;
38                 if(t2 < mid)
39                 {
40                     y -= mid-t2;
41                     if(i+w<n)
42                     f[i+w] += mid-t2;  //f数组记录到w个以后的不会加上mid-t2。
43                     tmp += mid-t2;  //记录前面增加的值
44                 }
45                 if(y < 0) break;
46             }
47             if(y>=0)
48             {
49                 low = mid+1;
50                 ans = mid;  //记录下合法的答案,一直到最高点
51             }
52             else
53             hig = mid-1;  //减去1
54         }
55         printf("%d
", ans);
56     }
57     return 0;
58 }
原文地址:https://www.cnblogs.com/bfshm/p/3926379.html