【算法刷题日记第一篇】Codeforces Round 775(Div.1)A. Weird Sum

@[TOC]Codeforces Round 775(Div.1)A. Weird Sum

题目及来源

  1. 题目来源: 11月13日灵茶试炼
  2. 题目描述:
    Egor 有一张大小为 n × m n \times m n×m 的表格,其中行的编号为 1 1 1 n n n ,列的编号为 1 1 1 m m m 。每个单元格都有一种颜色,可以用 1 1 1 1 0 5 10^5 105 的整数表示。
    我们把位于第 r r r 行和第 c c c 列交叉处的单元格称为 ( r , c ) (r, c) (r,c) 。我们将两个单元格 ( r 1 , c 1 ) (r_1, c_1) (r1,c1) ( r 2 , c 2 ) (r_2, c_2) (r2,c2) 之间的曼哈顿距离定义为它们之间最短路径的长度,路径中的每个连续单元格必须有一个公共边。路径可以穿过任何颜色的单元格。例如,在表格 3 × 4 3 \times 4 3×4 中, ( 1 , 2 ) (1, 2) (1,2) ( 3 , 3 ) (3, 3) (3,3) 之间的曼哈顿距离为 3 3 3 ,其中一条最短路径如下: ( 1 , 2 ) → ( 2 , 2 ) → ( 2 , 3 ) → ( 3 , 3 ) (1, 2) \to (2, 2) \to (2, 3) \to (3, 3) (1,2)(2,2)(2,3)(3,3) .
    埃戈尔决定计算每对相同颜色的单元格之间的曼哈顿距离之和。请帮助他计算这个总和。
  3. Input
    第一行包含两个整数 n n n m m m ( 1 ≤ n ≤ m 1 \leq n \le m 1nm , n ⋅ m ≤ 100   000 n \cdot m \leq 100\,000 nm100000 ) - 表格的行数和列数。
    接下来的 n n n 行分别描述表格的一行。第 i i i 行包含 m m m 个整数 c i 1 , c i 2 , … , c i m c_{i1}, c_{i2}, \ldots, c_{im} ci1,ci2,,cim 。( 1 ≤ c i j ≤ 100   000 1 \le c_{ij} \le 100\,000 1cij100000 ) - 第 i i i 行中单元格的颜色。
  4. Output
    打印一个整数 - 每对相同颜色的单元格之间的曼哈顿距离之和。

题目思路

两点(x1, y1), (x2, y2)的曼哈顿距离就是 ∣ x 1 − x 2 ∣ + ∣ y 1 − y 2 ∣ |x1 - x2| + |y1 - y2| x1x2∣+y1y2∣
因为曼哈顿距离x, y 是相互不影响的所以可以将同一个数字的x,y先进行排序,然后
将其按照贡献法的思路算新加进来一个坐标对于答案的贡献为,例如前m个数的坐标分别为x1, x2, …, xm, 新加入的坐标为xj, 对于答案的贡献为 ( x j − x 1 ) + ( x j − x 2 ) + . . . + ( x j − x m ) (xj - x1) + (xj - x2) + ... + (xj - xm) (xjx1)+(xjx2)+...+(xjxm), 将该公式整理可得 m ∗ x j − ( x 1 + x 2 + . . . + x m ) m * xj - (x1 + x2 + ... + xm) mxj(x1+x2+...+xm)
所以可以排序后用前缀和来维护答案。

代码

  1. go语言版本代码如下
package main

import (
	"bufio"
	. "fmt"
	"os"
	"sort"
)

// func init() { debug.SetGCPercent(-1) } // 关闭垃圾收集

func run() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush() // 加速读取
	var n, m, v, ans int
	Fscan(in, &n, &m)
	f := func(p []int) {
		pre := 0
		for i, v := range p {
			ans += i*v - pre
			pre += v
		}
	}
	var matrix [100010][2][]int
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			Fscan(in, &v)
			matrix[v][0] = append(matrix[v][0], i)
			matrix[v][1] = append(matrix[v][1], j)
		}
	}
	for _, nums := range matrix {
		f(nums[0])
		sort.Ints(nums[1]) // slices.Sort(), 1.21版本
		f(nums[1])
	}
	Fprintln(out, ans)
}

func main() {
	run()
}

  1. C++语言版本代码如下
    C++必须得开long long数组,不然会爆
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
class Solution {
public:
    
    void solve() {
        int n, m;
        cin >> n >> m;
        LL v;
        vector<vector<vector<LL>>> matrix(100010, vector<vector<LL>>(2));
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                cin >> v;
                matrix[v][0].emplace_back(i);
                matrix[v][1].emplace_back(j);
            }
        }
        LL ans = 0;
        function<LL(vector<LL>)> f = [](vector<LL> p) -> LL {
            LL res = 0;
            LL pre = 0;
            for (LL i = 0; i < p.size(); i++) {
                res += i * p[i] - pre;
                pre += p[i];
            }
            return res;
        };
        for (int i = 1; i <= 100000; i++) {
            ans += f(matrix[i][0]);
            sort(matrix[i][1].begin(), matrix[i][1].end());
            ans += f(matrix[i][1]);
        }
        cout << ans << '\n';
    }
};
static int fast_io = [](){ 
	std::ios::sync_with_stdio(false); 
	cin.tie(nullptr); 
	cout.tie(nullptr);
	return 0;
}();
int main()
{
	auto *it = new Solution;
    it->solve();
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
根据提供的引用内容,Codeforces Round 511 (Div. 1)是一个比赛的名称。然而,引用内容中没有提供与这个比赛相关的具体信息或问题。因此,我无法回答关于Codeforces Round 511 (Div. 1)的问题。如果您有关于这个比赛的具体问题,请提供更多的信息,我将尽力回答。 #### 引用[.reference_title] - *1* [Codeforces Round 860 (Div. 2)题解](https://blog.csdn.net/qq_60653991/article/details/129802687)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Codeforces Round 867 (Div. 3)(A题到E题)](https://blog.csdn.net/wdgkd/article/details/130370975)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Codeforces Round 872 (Div. 2)(前三道](https://blog.csdn.net/qq_68286180/article/details/130570952)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wby__&&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值