E. Dima and Kicks
                                                             time limit per test 2 seconds
                                                             memory limit per test   256 megabytes
input

standard input

output

standard output

Dima is a good person. In fact, he's great. But all good things come to an end...

Seryozha is going to kick Dima just few times.. For this reason he divides the room into unit squares. Now the room is a rectanglen × m consisting of unit squares.

For the beginning, Seryozha put Dima in a center of some square. Then he started to kick Dima (it is known, that he kicks Dima at least once). Each time when Dima is kicked he flyes up and moves into one of four directions (up, left, right, down). On each move Dima passes k(k > 1) unit of the length in the corresponding direction. Seryozha is really kind, so he kicks Dima in such way that Dima never meets the walls (in other words, Dima never leave the room's space). Seryozha is also dynamic character so Dima never flies above the same segment, connecting a pair of adjacent squares, twice.

Seryozha kicks Dima for a long time, but Dima is not vindictive — Dima writes. Dima marked all squares in which he was staying or above which he was flying. Thanks to kicks, Dima does not remember thek value, so he asks you to find all possible values which matches to the Dima's records.

Input

The first line contains n andm (1 ≤ n, m ≤ 103) — size of the room.

Next n lines goes, each containsm numbers aij — Dima's notes:aij = 1, if Dima was staying in the square(i, j) or was flying above it. Otherwiseaij = 0.

At least one aij equals1.

Output

In a single line in accending order print all k (k > 1), which matches the Dima's notes. If there are no suchk and Dima invented this story with kicks, print -1.

看了别人的代码,思路至今仍未捋清。

在2和Min(n,m)之间枚举k值,遍历矩阵,多条件检测k值。(以后再详解。。。)

#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <set>
#include <string>
#include <math.h>
#define N 1010
using namespace std;
int n,m,tot;
int a[N][N];
int s0[N][N],s1[N][N],d[N][N];
int readInt(){        //输入挂
  char c;
  int n=0;
  c=getchar();
  while(c<'0'||c>'9') c=getchar();
  while(c>='0'&&c<='9'){
    n=n*10+c-'0';
    c=getchar();                      
  }    
  return n;
}
int fa[N*N];
int sx,sy;   //默认初始化为0
int ok(int x,int y){
  return x>=1&&x<=n&&y>=1&&y<=m ;    
}
int find(int i)      //并查集
{
  if(fa[i]==i)  return i;
  else  return find(fa[i]);   
}
int can(int k){
    int i,j,x,y,mx,my,tmp;
    int dd=0,fmx;
    fmx=(sx-1)/k,mx=(n-sx)/k,my=(m-sy)/k,dd=0;   //mx,my记录距离下墙、右墙的kick数
    for(i=-fmx;i<=mx;i++)
      for(j=0;j<=my;j++){
         d[i+fmx][j]=0;
         int num=(i+fmx)*(my+1)+j;
         fa[num]=num;
      }
    for(i=-fmx;i<=mx;i++){
      for(j=0;j<=my;j++){
        x=sx+i*k;     //所能到达的位置
        y=sy+j*k;                   
        if(!a[x][y])  continue;
        dd++;
        if(ok(x+k,y)&&a[x+k][y]){   //向下走
          tmp=s0[x+k-1][y]-s0[x][y];
          if(tmp==k-1){
            d[i+fmx][j]++;
            d[i+1+fmx][j]++;
            dd+=k-1;
            fa[find((i+fmx)*(my+1)+j)]=fa[find((i+1+fmx)*(my+1)+j)];             
          }    
          else if(tmp>0)  return 0;                   
        }
        if(ok(x,y+k)&&a[x][y+k]){  //向右走
          tmp=s1[x][y+k-1]-s1[x][y];
          if(tmp==k-1){
            d[i+fmx][j]++;
            d[i+fmx][j+1]++;
            dd+=k-1;
            fa[find((i+fmx)*(my+1)+j)]=fa[find((i+fmx)*(my+1)+j+1)];             
          }    
          else if(tmp>0)  return 0;                          
        }        
      }                      
    }
    if(dd!=tot)  return 0;        //所经过的单元总数
    int cnt=0,thef=find((0+fmx)*(my+1)+0);
    for(i=-fmx;i<=mx;i++)
      for(j=0;j<=my;j++){
        cnt+=d[i+fmx][j]&1;                   
      }
    for(i=-fmx;i<=mx;i++)
      for(j=0;j<=my;j++){
        x=sx+i*k;
        y=sy+j*k;
        if(!a[x][y])  continue;
        if(find((i+fmx)*(my+1)+j)!=thef)   return 0;
      }
    return cnt<=2;
}
int main()
{
  int i,j,k;
  while(scanf("%d %d",&n,&m)!=EOF){
    tot=0;
    for(i=1;i<=n;i++)
      for(j=1;j<=m;j++){  
        //scanf("%d",&a[i][j]);
        a[i][j]=readInt();
        tot+=a[i][j];         //通过的总单元数            
      }
    if((n<3&&m<3)|| tot==1){
       printf("-1\n");             
    }
    else{
     for(i=1;i<=n;i++)
       for(j=1;j<=m;j++){  
        s0[i][j]=s0[i-1][j]+a[i][j];
        s1[i][j]=s1[i][j-1]+a[i][j];            
       }
     sx=sy=0;
     for(j=1;j<=m;j++){      //纵向搜索第一个不为0的单元位置
       for(i=1;i<=n;i++){
        if(a[i][j]){
          sx=i;sy=j; break;             
        }                  
       }                  
       if(sx) break;
     }
     int flag=1;
     for(k=2;k<=min(n,m);k++){
           //printf("can(%d)=%d\n",k,can(k));
           if(can(k)){
             if(flag)  flag=0;
             else   printf(" ");
             printf("%d",k);         
           }                                                            
     }
     if(flag)  printf("-1\n");
     else printf("\n");
    }         
  }
  return 0;
}

Codeforces Round #208 E. Dima and Kicks的更多相关文章

  1. Codeforces Round #208 (Div. 2) 358D Dima and Hares

    题目链接:http://codeforces.com/problemset/problem/358/D 开始题意理解错,整个就跪了= = 题目大意:从1到n的位置取数,取数的得到值与周围的数有没有取过 ...

  2. Codeforces Round #208 (Div. 2) A.Dima and Continuous Line

    #include <iostream> #include <algorithm> #include <vector> using namespace std; in ...

  3. Codeforces Round #208 (Div. 2) B Dima and Text Messages

    #include <iostream> #include <algorithm> #include <string> using namespace std; in ...

  4. Codeforces Round #208 (Div. 2)

    A - Dima and Continuous Line 水题:直接模拟: #include<cstdio> #define maxn 1005 using namespace std; ...

  5. Codeforces Round #553 B. Dima and a Bad XOR

    题面: 传送门 题目描述: 题意很简单:在一个N*M的矩阵中(N行M列),问是否可以:每行选一个整数,使他们的异或和大于0.如果不可以,输出"NIE":如果可以,输出"T ...

  6. Codeforces Round #223 (Div. 2) A

    A. Sereja and Dima time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  7. Codeforces Round #366 (Div. 2) ABC

    Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...

  8. Codeforces Round #354 (Div. 2) ABCD

    Codeforces Round #354 (Div. 2) Problems     # Name     A Nicholas and Permutation standard input/out ...

  9. Codeforces Round #368 (Div. 2)

    直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...

随机推荐

  1. 【HDU 6021】 MG loves string (枚举+容斥原理)

    MG loves string  Accepts: 30  Submissions: 67  Time Limit: 2000/1000 MS (Java/Others)  Memory Limit: ...

  2. [CodeForces-763C]Timofey and remoduling

    题目大意: 告诉你一个长度为n的等差数列在模m意义下的乱序值(互不相等),问是否真的存在满足条件的等差数列,并尝试构造任意一个这样的数列. 思路: 首先我们可以有一个结论: 两个等差数列相等,当且仅当 ...

  3. introduction to my business card

    http://www.t4f.org/projects/business-card/ After 4 years working in an international IT consulting c ...

  4. PHP str_pad() 函数

    str_pad() 函数把字符串填充为指定的长度. 进入 详细介绍页面

  5. ookla 网络上传下载 PING 测试

    1.登陆http://www.ookla.com/ 2.点选Explore Speedtest Custon 3. 1.start for free 或者 2.measure your network ...

  6. winform 取消datagridview第一行选中状态

    C# WinForm 取消DataGridView的默认选中Cell 使其不反蓝 http://www.cnblogs.com/freeliver54/archive/2009/02/16/13913 ...

  7. 对printf函数的理解1

    看如下代码: #include <stdio.h> int main(int argc, const char *argv[]) { printf("%s\n",&qu ...

  8. Java:泛型在编译时会被檫除,Eclipse 如何给出智能提示?

    背景 Java 的泛型是一种语法糖,编译时会被“檫除”,参考文章:http://docs.oracle.com/javase/tutorial/java/generics/,如果没有源代码,Eclip ...

  9. GoF设计模式三作者15年后再谈模式

    Erich Gamma, Richard Helm, 和 Ralph Johnson在GoF设计模式发表15年以后,再谈模式,另外一位作者,也是四色原型的发明者Peter已经过世. 提问者:如今有85 ...

  10. OpenCV使用FLANN进行特征点匹配

    使用FLANN进行特征点匹配 目标 在本教程中我们将涉及以下内容: 使用 FlannBasedMatcher 接口以及函数 FLANN 实现快速高效匹配( 快速最近邻逼近搜索函数库(Fast Appr ...