Vlad and a Sum of Sum of Digits&&洛谷P1605-迷宫&&改变数组元素 24.2.21刷题

Cf Round 928 (Div.4)-C. Vlad and a Sum of Sum of Digits

Please note that the time limit for this problem is only 0.5 seconds per test.

Vladislav wrote the integers from 1 to n, inclusive, on the board. Then he replaced each integer with the sum of its digits.

What is the sum of the numbers on the board now?

For example, if n=12=12 then initially the numbers on the board are:

1,2,3,4,5,6,7,8,9,10,11,12.1,2,3,4,5,6,7,8,9,10,11,12.

Then after the replacement, the numbers become:

1,2,3,4,5,6,7,8,9,1,2,3.1,2,3,4,5,6,7,8,9,1,2,3.

The sum of these numbers is 1+2+3+4+5+6+7+8+9+1+2+3=511+2+3+4+5+6+7+8+9+1+2+3=51. Thus, for n=12 the answer is 5151.

**请注意,本问题每次测试的时间限制仅为 0.5 秒。

弗拉迪斯拉夫在黑板上写下了从 1 到 n 的整数。弗拉迪斯拉夫在黑板上写下了从 1 到 n 的整数,然后将每个整数替换为其数位之和。

现在黑板上的数字之和是多少?

例如,如果是 n=12 ,那么最初黑板上的数字是

1,2,3,4,5,6,7,8,9,10,11,12.1,2,3,4,5,6,7,8,9,10,11,12.

那么在替换之后,数字变成了

1,2,3,4,5,6,7,8,9,1,2,3.1,2,3,4,5,6,7,8,9,1,2,3.

这些数字之和为 1+2+3+4+5+6+7+8+9+1+2+3=511+2+3+4+5+6+7+8+9+1+2+3=51 。因此,对于 n=12 ,答案是 5151 。

       最大的问题是时间限制只有0.5秒。。

        比赛的时候用的前缀和,但是数据量的问题,加上计算数位和需要一个while语句,所以当时也是不出意料的TLE了(菜,就多练)

        题目的答案其实是固定的。n = 7的时候答案就是51,n = 12的时候答案就是5151。所以可以在一开始对答案进行预处理,将我们会用到的答案全部存入ans数组,最后输出对应的元素即可。

        尽量压缩时间,函数写计算数位和。

AC代码:

#include<iostream>
#include<algorithm>
#include<cmath>
typedef long long ll;
const int M = 200005;

using namespace std;

int ans[M];

int plx(int x)
{
	int ans = 0;
	while (x)
	{
		ans += (x % 10);
		x /= 10;
	}
	return ans;
}

void solve()
{
	int n;
	cin >> n;
	cout << ans[n] << '\n';
}

int main()
{
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	for (int i = 1; i < M; i++)
		ans[i] = plx(i) + ans[i - 1];
	int t;
	cin >> t;
	while (t--)
		solve();
	return 0;
}

洛谷P1605-迷宫

题目描述

给定一个 N×M 方格的迷宫,迷宫里有 T 处障碍,障碍处不可通过。

在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。

给定起点坐标和终点坐标,每个方格最多经过一次,问有多少种从起点坐标到终点坐标的方案。

输入格式

第一行为三个正整数 N,M,T,分别表示迷宫的长宽和障碍总数。

第二行为四个正整数 SX,SY,FX,FY,SX,SY 代表起点坐标,FX,FY 代表终点坐标。

接下来 T 行,每行两个正整数,表示障碍点的坐标。

        DFS板子题,今天重新写了一下。

        二维数组DFS用到表示方向的d数组。

        d[5] = {-1,0,1,0,-1}

        此时定义x和y方向的新变量,通过两个变量模拟四个方向的移动

        对于判断是否接下来的一格,用f的值决定。注意的是,每次DPS之后要回溯到初始状态。

AC代码:

#include<iostream>
#include<algorithm>
#include<cmath>
typedef long long ll;
const int M = 200005;

using namespace std;

int n, m, t,cnt;
int sx, sy, fx, fy;
int a[15][15],f[15][15];
int d[5] = { -1,0,1,0,-1 };

void dfs(int x,int y)
{
	if (x == fx && y == fy)
	{
		cnt++;
		return;
	}
	for (int i = 0; i < 4; i++)
	{
		int l = x + d[i];
		int r = y + d[i+1];
		if (l >= 1 && r >= 1 && l <= n && r <= m && a[l][r] == 0 && f[l][r] == 0) 
        {
			f[l][r] = 1;
			dfs(l, r);
			f[l][r] = 0;
		}
	}
}

int main()
{
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	cin >> n >> m >> t>> sx >> sy >> fx >> fy;
	a[sx][sy] = 1;
	int p, q;
	for (int i = 1; i <= t; i++)
	{
		cin >> p >> q;
		a[p][q] = 1;
	}
	dfs(sx, sy);
	cout << cnt << '\n';
	return 0;
}

Acwing-每日一题:改变数组元素

解法一:

        思路:数字越大,改变的数字就越多。最终的数组构成,位于后面的数字可以覆盖前面的数字。可以从后往前遍历数组a,找到左边界,并将从左边界到当前位的元素都变为“1”。

AC代码:

#include<iostream>
#include<algorithm>
#include<cstring>
typedef long long ll;
const int M = 2000010;
const int INF = 0x3f3f3f3f;

using namespace std;

int a[M];

void solve()
{
	int n;
	cin >> n;
    memset(a,0,sizeof(a))
	for (int i = 1; i <= n; i++)
		cin >> a[i];
	int l = INF;
	for (int i = n; i >= 1; i--)
	{
		l = min(l, i - a[i] + 1);
		if (l <= i)
			a[i] = 1;
	}
	for (int i = 1; i <= n; i++)
		cout << a[i] << ' ';
	cout << '\n';
}

int main()
{
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	int t;
	cin >> t;
	while (t--)
		solve();
	return 0;
}

解法二:差分

        可以当差分板子的一道题(本来在Acwing就是板子题。。)

        核心代码是作为模板的cf函数和前缀和操作。因为差分可以看作前缀和的逆运算。(差分数组进行前缀和 == 原数组)

AC代码:

#include<iostream>
#include<cstring>
#include<algorithm>
typedef long long ll;
const int M = 200005;

using namespace std;

int a[M];

void cf(int x, int y)
{
	a[x]++;
	a[y + 1]--;
}

void solve()
{
	int n, k;
	cin >> n;
	memset(a, 0, size(a));
	for (int i = 1; i <= n; i++)
	{
		cin >> k;
		if (k == 0)
			continue;
		else if (k >= i)
			cf(1, i);
		else
			cf(i - k + 1, i);
	}
	for (int i = 1; i <= n; i++)
		a[i] += a[i - 1];
	for (int i = 1; i <= n; i++)
	{
		if (a[i] == 0)
			cout << 0 << ' ';
		else
			cout << 1 << ' ';
	}
	cout << '\n';
}

int main()
{
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	int t;
	cin >> t;
	while (t--)
		solve();
	return 0;
}
  • 19
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值