Codeforces Round #427 (Div. 2)
B. The number on the board
题意:
有一个数字,它的每个数位上的数字的和不小于等于k。现在他改变了若干位,变成了一个新的数n,问现在的数和原来的数最多有多少位不同。
思路:
如果现在的数字各位数字之和大于等于k,那么它就可能没有被改变。
反之,那么每个数的最大改变量就是9减去这个数,于是把9减去每个数得到的结果从大到小排序,用k减去现在的数位和得到的结果记为kk,遍历一遍差量数组,用kk去减,知道kk小于0跳出。
代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 using namespace std; 5 6 bool cmp(int a,int b) 7 { 8 return a > b; 9 } 10 11 int b[100005]; 12 13 int main() 14 { 15 long long k; 16 17 scanf("%I64d",&k); 18 19 char s[100005]; 20 21 long long sum = 0; 22 23 scanf("%s",s); 24 25 int len =strlen(s); 26 27 for (int i = 0;i < len;i++) 28 { 29 int t = s[i] - '0'; 30 b[i] = 9 - t; 31 sum += t; 32 } 33 34 35 if (sum >= k) printf("0\n"); 36 else 37 { 38 sort(b,b+len,cmp); 39 40 long long ans = k - sum; 41 42 int num = 0; 43 44 for (int i = 0;i < len;i++) 45 { 46 ans -= b[i]; 47 48 num++; 49 50 if (ans <= 0) 51 { 52 break; 53 } 54 } 55 56 printf("%d\n",num); 57 } 58 59 return 0; 60 }
C. Star sky
题意:
在一个平面直角坐标系上,有闪亮的星星。每个星星的最大亮度为相同的c,每颗星星有不同的起始亮度si,从开始时刻起每一秒亮度加1,如果当前亮度为c,那么下一秒就是0.
一开始给出每个星星的坐标和初始亮度,之后给出若干个询问,给出此时的时刻,矩形的左下角的坐标和右上角的坐标,统计在这个矩形内的所有的星星的亮度的总和(包括边界)。
思路:
一开始用暴力直接tle,遂在赛后看题解补题。前缀法,总的来说就是sum (a,b,c,d) = pre(c-1,b) - pre(a,y-1)-pre(c - 1,d - 1);
什么意思呢,pre(a,b)代表的是在(0,0)到(a,b)这个区间内的所有星星的总数(当然是分亮度的),看图
在每个询问的时候,统计0到c的亮度的星星在t时刻的亮度 (j + t) % (c + 1)
然后对亮度进行累加。(中间把j写成了tt,wa了无数次,还是要深入思考,彻底搞懂)
代码:
#include <stdio.h> #include <string.h> int pre[105][105][15]; int main() { int n,q,c; scanf("%d%d%d",&n,&q,&c); for (int i = 0;i < n;i++) { int x,y,s; scanf("%d%d%d",&x,&y,&s); pre[x][y][s]++; } for (int i = 1;i <= 100;i++) for (int j = 1;j <=100;j++) for (int k = 0;k <= c;k++) { pre[i][j][k] += (pre[i-1][j][k] + pre[i][j-1][k] - pre[i-1][j-1][k]); } for (int i = 0;i < q;i++) { int t,x,y,a,b; scanf("%d%d%d%d%d",&t,&x,&y,&a,&b); int ans = 0; for (int j = 0;j <= c;j++) { int tt = (j+t) % (c + 1); int tmp = pre[a][b][j] - pre[a][y-1][j] - pre[x-1][b][j] + pre[x-1][y-1][j]; ans += tmp * tt; } printf("%d\n",ans); } return 0; }
康复训练中~欢迎交流!