Codeforces 366E Dima and Magic Guitar 暴力

题目大意:

就是现在有一个n*m的矩阵当中所有的数都是[1~k]以内的正整数, 现在对于一串字符s, 这个s当中相邻的两个字符在n*m的矩阵当中对应的最远距离是多少

(x1, y1)和(x2, y2)之间的距离定义为 |x1 - x2| + |y1 - y2|


大致思路:

首先可以注意到:

|x1 - x2| + |y1 - y2|
= (x1 + y1) - (x2 + y2) (x1 >= x2 && y1 >= y2)
= (-x1 + y1)- (-x2 + y2) (x1 < x2 && y1 >= y2)
= (-x1 - y1) - (-x2 - y2) (x1 < x2 && y1 < y2)
= (x1 - y1) - (x2 - y2) (x1 >= x2 && y1 < y2)

如果我们令 a[i][0] =  -xi - yi, a[i][1] = xi + yi, a[i][2] = -xi + yi, a[i][3] = xi - yi 这些对应的最大值, 用a[i][4~7]表示对应于a[i][0~4]的最小值

显然就是求a[x][0~3] - a[y][4~7]的最大值了

其中(xi, yi)是i这个数出现的坐标

剩下的就是遍历s中的所有相邻字符了...


代码如下:

Result  :  Accepted     Memory  :  100 KB     Time  :  529 ms

/*
 * Author: Gatevin
 * Created Time:  2015/3/23 14:20:17
 * File Name: Chitoge_Kirisaki.cpp
 */
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
const double eps(1e-8);
typedef long long lint;

int n, m, k, s;
int a[10][8];

/*
 * |x1 - x2| + |y1 - y2|
 * = (x1 + y1) - (x2 + y2) (x1 >= x2 && y1 >= y2)
 * = (-x1 + y1)- (-x2 + y2) (x1 < x2 && y1 >= y2)
 * = (-x1 - y1) - (-x2 - y2) (x1 < x2 && y1 < y2)
 * = (x1 - y1) - (x2 - y2) (x1 >= x2 && y1 < y2)
 * a[x][1] - a[y][1]
 * a[x][2] - a[y][2]
 * a[x][0] - a[y][0]
 * a[x][3] - a[y][3]
 */
int main()
{
    scanf("%d %d %d %d", &n, &m, &k, &s);
    int x, y;
    for(int i = 0; i < 10; i++)
        for(int j = 0; j < 4; j++)
            a[i][j] = -0x3f3f3f3f, a[i][j + 4] = 0x3f3f3f3f;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
        {
            scanf("%d", &x);
            a[x][0] = max(a[x][0], i - j);
            a[x][1] = max(a[x][1], i + j);
            a[x][2] = max(a[x][2], -i - j);
            a[x][3] = max(a[x][3], -i + j);
            a[x][4] = min(a[x][4], i - j);
            a[x][5] = min(a[x][5], i + j);
            a[x][6] = min(a[x][6], -i - j);
            a[x][7] = min(a[x][7], -i + j);
        }
    int ans = -0x3f3f3f3f;
    scanf("%d", &x);
    for(int i = 1; i < s; i++)
    {
        scanf("%d", &y);
        for(int j = 0; j < 4; j++)
            ans = max(ans, a[x][j] - a[y][j + 4]);
        x = y;
    }
    printf("%d\n", ans);
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值