AtCoder Grand Contest 066 A. Adjacent Difference(构造 思维题)

题目

n*n(n<=500)的矩阵,第i行第j列的数a[i][j](-1e3<=a[i][j]<=1e3)

给出一个值d(1<=d<=1000),你可以执行若干次操作,每次你可以选一个位置,

并给这个位置的数+x(x可以为负),代价是x的绝对值

在满足总代价不超过n*n*d/2的情况下,

使得新矩阵相邻项的差的绝对值>=d,输出新矩阵

相邻:a[i][j]和a[i][j+1]认为相邻,a[i][j]和a[i+1][j]认为相邻

思路来源

jiangly B站讲解

题解

很容易验证题解是正确的,只是很难想到这个做法,想不到就没法做

先将矩阵黑白染色,

第一次,将黑色的数改成最近的d的奇数倍,将白色的数改成最近的d的偶数倍

第二次,将黑色的数改成最近的d的偶数倍,将白色的数改成最近的d的奇数倍

不难发现,由于每个数向左向右构成了一个长为d的区间,所以两次操作的代价和是d*n*n

所以较小代价的那次就是不超过n*n*d/2的,输出即可

代码

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
typedef long long ll;
typedef double db;
typedef pair<int,int> P;
#define fi first
#define se second
#define pb push_back
#define dbg(x) cerr<<(#x)<<":"<<x<<" ";
#define dbg2(x) cerr<<(#x)<<":"<<x<<endl;
#define SZ(a) (int)(a.size())
#define sci(a) scanf("%d",&(a))
#define pt(a) printf("%d",a);
#define pte(a) printf("%d\n",a)
#define ptlle(a) printf("%lld\n",a)
#define debug(...) fprintf(stderr, __VA_ARGS__)
using namespace std;
const int N=505;
int n,d,a[N][N],b[N][N];
int main(){
    sci(n),sci(d);
    rep(i,1,n){
        rep(j,1,n){
            sci(a[i][j]);
        }
    }
    rep(k,0,1){
        int sum=0;
        rep(i,1,n){
            rep(j,1,n){
                int x=(i+j+k)%2,v=a[i][j]/d*d,v2;
                if(v<=a[i][j] && a[i][j]<=v+d)v2=v+d;
                else v2=v-d;
                b[i][j]=((v/d+x)%2==0?v:v2);
                sum+=abs(b[i][j]-a[i][j]);
            }
        }
        if(sum<=n*n*d/2){
            rep(i,1,n){
                rep(j,1,n){
                    printf("%d%c",b[i][j]," \n"[j==n]);
                }
            }
            return 0;
        }
    }
    assert(false);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小衣同学

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

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

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

打赏作者

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

抵扣说明:

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

余额充值