Sonya and Matrix CodeForces - 1004D (构造)

题目链接

题意:给出一种矩阵,有且只有一个位置是0,其余位置的值是与0的曼哈顿距离。现给你t个数,问这t个数是否能构成一个上述矩阵,若可以,输出矩阵的大小以及0的位置。

分析:由于矩阵是由大小n*m,0的位置(x,y)确定,只要有了这4个参数我们就可以求出除0位置以外的所有的值 。

我们令0在上半个矩阵,(在下半个也是一样的,可以对称过去)
再我们根据这个矩阵里面,当矩阵无限大,每个数的个数就是值*4,(1出现4次,2出现8次,3出现12次…) 可以知道从1开始枚举,最先缺少的数就是0的x坐标。

然后我们枚举t的因子作为n,m的值,利用 n-x+m-y==mmax (mmax为离0位置最远的曼哈顿距离) 求出y=n-x+m-mmax

于是n m x y全都有了 ,再求出其他位置的值的个数情况与题目比较即可。

时间复杂度O(sqrt(t)*t) 大概1e9 cf的机子跑200ms左右orz

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1e6+5;
const int mx = 40;
const int mod = 1e9+5;
const ll inf = 34359738370;
const int INF = 1e9+5;
int c[maxn];//每个数出现的次数
int t,n,m,x=1,y,maxx;//0的位置 (x,y) x为最先缺少的数  y=n-x+m-mmax
int c1[maxn];//用于验证的时候和c对比
int dis(int a,int b)
{
    return abs(a-x)+abs(b-y);
}
bool check()
{
    for(int k=0;k<t;k++)
    {
        if(c[k] != c1[k])
        {
            return 0;
        }
    }
    return 1;
}
int main()
{
    bool ok=0;
    scanf("%d",&t);
    for(int i=1;i<=t;i++)
    {
        int a;
        scanf("%d",&a);
        ++c[a];
        maxx=max(maxx,a);
    }
    for(int i=1;i<=t;i++)
    {
        if(c[i] != i*4) //最先开始缺少的数
        {
            x=i;
            break;
        }
    }
    for(int i=1;i<=t;i++)//枚举t的因子  n*m==t
    {
        if(t%i) continue;
        n=i,m=t/i;
        y=n-x+m-maxx;
        if(x < 1 || x > n || y < 1 || y > m)	continue;
        memset(c1,0,sizeof(c1));
        for(int k=1;k<=n;k++)
        {
            for(int l=1;l<=m;l++)
            {
                ++c1[dis(k,l)];
            }
        }
        if(check())
        {
            printf("%d %d\n%d %d\n",n,m,x,y);
            ok=1;
            break;
        }
    }
    if(!ok) puts("-1");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值