题意:给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 }
C 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 }