Codeforces Round #495 (Div. 2)D. Sonya and Matrix(数学思维+构造)

D. Sonya and Matrix

题意:

输入 t ( 1 e 6 ) t(1e6) t(1e6),表示有一个矩形 n × m = t n\times m=t n×m=t
接下来 a 1 , a 2 … , a t ( 0 , t ) a_1,a_2\dots,a_t(0,t) a1,a2,at(0,t)表示矩形内的数。
问构造 n , m , x , y n,m,x,y n,m,x,y;其中 n , m n,m n,m表示矩形,在 ( x , y ) (x,y) (x,y) 0 0 0, ( x + 1 , y ) , ( x − 1 , y ) , ( x , y − 1 ) , ( x , y + 1 ) (x+1,y),(x-1,y),(x,y-1),(x,y+1) (x+1,y),(x1,y),(x,y1),(x,y+1) 1 1 1,紧接着填 2 , 3 … 2,3\dots 2,3,以此类推。要求填的数和 a a a数组符合,不要求顺序。

题解:

考虑最大填的数为 ( 1 , 1 ) , ( n , m ) (1,1),(n,m) (1,1),(n,m)的距离,不妨设 ( x , y ) (x,y) (x,y)距离 ( n , m ) (n,m) (n,m)最远,于是就有
m x = n + m − x − y mx=n+m-x-y mx=n+mxy,又 n × m = t n\times m=t n×m=t n , m n,m n,m可枚举, m x mx mx根据数组可知,还有 x , y x,y x,y未知。
然后,可以确定第一个小于 4 × i 4\times i 4×i的数字 i i i,不妨设 x = i x=i x=i,于是所有变量都已知了,最后判断一下就好了。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+9;
int t,a[N],mx,low;
int tmp[N];
void check(int n,int m){
    int x=low,y=n+m-mx-x;
    memset(tmp,0,sizeof(tmp));
    if(x<=0||x>n||y<=0||y>m)return;
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)tmp[abs(i-x)+abs(j-y)]++;
    for(int i=0;i<N;i++)if(tmp[i]!=a[i])return;
    cout<<n<<" "<<m<<endl;
    cout<<x<<" "<<y<<endl;
    exit(0);
}
int main(){
  //  freopen("tt.in","r",stdin),freopen("tt.out","w",stdout);
    cin>>t;
    for(int i=1,x;i<=t;i++)cin>>x,mx=max(mx,x),a[x]++;
    for(int i=0;;i++)if(a[i]<4*i){low=i;break;}
    for(int i=1;i<=sqrt(t);i++)if(t%i==0){
        check(i,t/i);
        check(t/i,i);
    }
    cout<<-1<<endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值