Codeforces Round #427 (Div. 2)

时间:2023-03-08 18:52:57
Codeforces Round #427 (Div. 2)

B. The number on the board

题意:

有一个数字,它的每个数位上的数字的和不小于等于k。现在他改变了若干位,变成了一个新的数n,问现在的数和原来的数最多有多少位不同。

思路:

如果现在的数字各位数字之和大于等于k,那么它就可能没有被改变。

反之,那么每个数的最大改变量就是9减去这个数,于是把9减去每个数得到的结果从大到小排序,用k减去现在的数位和得到的结果记为kk,遍历一遍差量数组,用kk去减,知道kk小于0跳出。

代码:

 #include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std; bool cmp(int a,int b)
{
return a > b;
} int b[]; int main()
{
long long k; scanf("%I64d",&k); char s[]; long long sum = ; scanf("%s",s); int len =strlen(s); for (int i = ;i < len;i++)
{
int t = s[i] - '';
b[i] = - t;
sum += t;
} if (sum >= k) printf("0\n");
else
{
sort(b,b+len,cmp); long long ans = k - sum; int num = ; for (int i = ;i < len;i++)
{
ans -= b[i]; num++; if (ans <= )
{
break;
}
} printf("%d\n",num);
} return ;
}

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)这个区间内的所有星星的总数(当然是分亮度的),看图

Codeforces Round #427 (Div. 2)

在每个询问的时候,统计0到c的亮度的星星在t时刻的亮度 (j + t) % (c + 1)

然后对亮度进行累加。(中间把j写成了tt,wa了无数次,还是要深入思考,彻底搞懂)

代码:

#include <stdio.h>
#include <string.h> int pre[][][]; int main()
{
int n,q,c; scanf("%d%d%d",&n,&q,&c); for (int i = ;i < n;i++)
{
int x,y,s; scanf("%d%d%d",&x,&y,&s); pre[x][y][s]++;
} for (int i = ;i <= ;i++)
for (int j = ;j <=;j++)
for (int k = ;k <= c;k++)
{
pre[i][j][k] += (pre[i-][j][k] + pre[i][j-][k] - pre[i-][j-][k]);
} for (int i = ;i < q;i++)
{
int t,x,y,a,b; scanf("%d%d%d%d%d",&t,&x,&y,&a,&b); int ans = ; for (int j = ;j <= c;j++)
{
int tt = (j+t) % (c + ); int tmp = pre[a][b][j] - pre[a][y-][j] - pre[x-][b][j] + pre[x-][y-][j]; ans += tmp * tt;
} printf("%d\n",ans);
} return ;
}