Codeforces Round #495 (Div. 2) D. Sonya and Matrix
Posted y-meng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #495 (Div. 2) D. Sonya and Matrix相关的知识,希望对你有一定的参考价值。
链接:http://codeforces.com/contest/1004/problem/D
题意:给你t个数字(a1,a2......at),要你组成一个n x m的矩阵,这个矩阵满足这样的条件 ①矩阵里面的元素到“0”这个元素的曼哈顿距离为元素值大小。曼哈顿距离:两个点坐标差的绝对值之和。
现在问你的是输出n,m以及元素“0”的坐标(x,y);如果不存在这样的矩阵,输出“-1”。
注意:起点坐标为(1,1)。
分析:首先我们假设“0”的坐标为(x,y),它到(1,1)点的距离为a,到(n,m)点的距离为b;显而易见的是,b的大小就是元素ai的最大值。
因此我们可以等到这样的等式:
a=x-1+y-1;①
b=n-x+m-y;②
由①②可得 n+m=a+b+2;
所以 a=n+m-2-b;代入①得
y=n+m-b-x;
n,m显然很好球出来,b也已经知道,现在就差x如何求呢?
x稍微了解一下就能得出:让我们找到最小的i,是的列表中出现i的次数不等于4*i,则x=i;
大致的框架已经弄出来了,细节东西就要看自己了,我已经在代码中标明了一些细节东西,需要注意的。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1e6+10; 4 int a[N],d[N]; 5 int t; 6 int n,m; 7 int x,y; 8 int b;///矩阵角落到"0"的最大距离 9 ///y=n+m-b-x 10 int main() 11 { 12 while(scanf("%d",&t)!=EOF){ 13 memset(a,0,sizeof(a)); 14 b=0; 15 for(int i=1;i<=t;i++){ 16 int num; 17 scanf("%d",&num); 18 a[num]++; 19 b=max(b,num); 20 } 21 x=1;///x需要初始化为1,因为x的最小值为1,我们可能在下面的循环中,找不到这样的x 22 ///从而导致x的值不确定.eg:1 0这一组数据。 23 for(int i=1;i<b;i++) 24 if(a[i]!=4*i){ 25 x=i; 26 break; 27 } 28 int flag2=1; 29 for(n=1;n<=t;n++){ 30 if(t%n==0){ 31 m=t/n; 32 y=n+m-b-x; 33 34 memset(d,0,sizeof(d)); 35 for(int i=1;i<=n;i++){ 36 for(int j=1;j<=m;j++){ 37 int temp=abs(i-x)+abs(j-y); 38 d[temp]++; 39 } 40 } 41 int flag=1; 42 for(int i=0;i<=b;i++){///这里i要从0开始比较,因为有可能出现多个"0"的情况. 43 if(a[i]!=d[i]){ 44 flag=0; 45 break; 46 } 47 } 48 if(flag){ 49 printf("%d %d ",n,m); 50 printf("%d %d ",x,y); 51 flag2=0; 52 break; 53 } 54 } 55 } 56 if(flag2)printf("-1 "); 57 } 58 59 return 0; 60 }
想得到就简单,想不到就难~!
以上是关于Codeforces Round #495 (Div. 2) D. Sonya and Matrix的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #495 (Div. 2) D. Sonya and Matrix
Codeforces Round #495 (Div. 2) D. Sonya and Matrix
Codeforces Round #436 E. Fire(背包dp+输出路径)
[ACM]Codeforces Round #534 (Div. 2)