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. zTree通过指定ID找到节点并选中

    zTree = $.fn.zTree.getZTreeObj("treeDemo");//treeDemo界面中加载ztree的div var node = zTree.getNo ...

  2. GeoIP的使用

    GeoIP介绍: 什么是GepIP ? 所谓GeoIP,就是通过来访者的IP, 定位他的经纬度,国家/地区,省市,甚至街道等位置信息.这里面的技术不算难题,关键在于有个精准 的数据库.有了准确的数据源 ...

  3. bzoj 2152

    /************************************************************** Problem: 2152 User: idy002 Language: ...

  4. 厄拉多塞筛法和普通方法求素数表(python实现)

    厄拉多赛筛法(sieve of Eratosthenes): 想要得到一个不大于N的数所有素数,可以先找到不超过根号N的所有素数,设2 = p1 < p2 < ......<pk ≤ ...

  5. hihocoder1489 Legendary Items (微软2017年预科生计划在线编程笔试)

    http://hihocoder.com/problemset/problem/1489 笔试题第一道,虽然说第一道都很水,但是我感觉这题不算特别水把..这道题我就卡住了我记得,tle,最后只有30分 ...

  6. react-native-communications 电话、短信、邮件、浏览器

    第一种方法:Linking:调用系统的电话.短信.邮件.浏览器等功能 Linking.canOpenURL(this.props.url).then(supported => { if (!su ...

  7. BZOJ 2301: [HAOI2011]Problem b (莫比乌斯反演)

    2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 436  Solved: 187[Submit][S ...

  8. PHP str_pad() 函数

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

  9. Linux Kernel 4.9 & BBR

    https://www.mxgw.info/t/linux-kernel-4-9-bbr.html?utm_source=tuicool&utm_medium=referral

  10. JAVA-数据类型、变量、常量

    http://blog.csdn.net/yuhailong626/article/details/7245571 http://www.cnblogs.com/JackieADBM/p/534222 ...