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. Xcode 7.0正式版发布了

    Xcode 7.0正式版发布了     下载地址:链接: http://pan.baidu.com/s/1FNkPS 密码: ee42     本文由大学霸整理,转载请注明出处,尊重IT人!

  2. TCP 的那些事儿-1

    TCP是一个巨复杂的协议,因为他要解决很多问题,而这些问题又带出了很多子问题和阴暗面.所以学习TCP本身是个比较痛苦的过程,但对于学习的过程却能让人有很多收获.关于TCP这个协议的细节,我还是推荐你去 ...

  3. RabbitMQ (一)

    学习RabbitMQ 可以先先了解一下AMQP 简单介绍: AMQP从一开始就设计成为开放标准,以解决众多的消息队列需求和拓扑结构问题,凭借开发,任何人都可以执行这一标准.针对标准编码的任何人都可以和 ...

  4. shell中的cat和文件分界符(<<EOF) (转)

    原文地址: http://blog.csdn.net/mosesmo1989/article/details/51123257 在shell中,文件分界符(通常写成EOF,你也可以写成FOE或者其他任 ...

  5. android 捕获所有异常 未捕获的异常

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 定义一个类 继承 应用, 实现 未捕获异常处理器 uncaughtExceptionHa ...

  6. 一个安卓应用 多少个 dalvik 虚拟机

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 一个

  7. java 抽象类 接口 区别

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 接口 里面 都是抽象方法. 接口里面的 字段 都是 public static fina ...

  8. luogu P3383 【模板】线性筛素数

    题目描述 如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内) 输入输出格式 输入格式: 第一行包含两个正整数N.M,分别表示查询的范围和查询的个数. 接下来M行每行 ...

  9. [BZOJ4872][六省联考2017]分手是祝愿(期望DP)

    4872: [Shoi2017]分手是祝愿 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 516  Solved: 342[Submit][Statu ...

  10. bzoj1798 维护序列

    Description 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2 ...