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. POJ 3735 Training little cats<矩阵快速幂/稀疏矩阵的优化>

    Training little cats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 13488   Accepted:  ...

  2. 【BZOJ 2711】 2711: [Violet 2]After 17 (0-1 背包)

    2711: [Violet 2]After 17 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 224  Solved: 153 Description ...

  3. [NC13A]反蝴蝶效应/[SPOJ-NPC2014D]General Joke

    [NC13A]反蝴蝶效应/[SPOJ-NPC2014D]General Joke 题目大意: 按顺序访问\(A_{1\sim n}(n\le10^5)\),经过\(A_i\)时身上必须有\(A_i\) ...

  4. org.json.JSONObject and no properties discovered 错误解决

    自己在搭建SSM框架的时候(Spring + spring mvc + mybatis)报错内容如下: No serializer found for class org.json.JSONObjec ...

  5. AC自动机详解(附加可持久化AC自动机)

    AC自动机 AC自动机,说白了就是在trie树上跑kmp(其实个人感觉比kmp容易理解).是一种多匹配串,单个主串的匹配.概括来说,就是将多个匹配串构造一个trie树,对于每个trie树的节点构造nx ...

  6. JDK源码(1.7) -- java.util.ListIterator<E>

    java.util.ListIterator<E> 源码分析(JDK1.7) ------------------------------------------------------- ...

  7. 温故而知新---Java(一)

    学习不仅要学习新的东西,而且还要时不时的回过头捡漏... 本文参考老马说编程系列等文,在此推荐大家关注老马说编程系列文章 正文 基础知识 数据类型主要是为了对数据进行分类,方便理解和操作,在Java中 ...

  8. PAT甲级1003. Emergency

    PAT甲级1003. Emergency 题意: 作为一个城市的紧急救援队长,你将得到一个你所在国家的特别地图.该地图显示了几条分散的城市,连接着一些道路.每个城市的救援队数量和任何一对城市之间的每条 ...

  9. Windows UWP开发系列 – 控件默认样式

    今天用一个Pivot控件的时候,想修改一下它的Header样式,却发现用Blend和VS无法导出它的默认样式了,导致无法下手,不知道是不是Blend的bug. 在网上搜了一下,在MSDN上还是找到了它 ...

  10. Spark编程指南V1.4.0(翻译)

    Spark编程指南V1.4.0 ·        简单介绍 ·        接入Spark ·        Spark初始化 ·        使用Shell ·        在集群上部署代码 ...