1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include <iostream>
#include "dzialka.h"
#include "message.h"
using namespace std;

struct Cell{
	int isUsable;
	int left, down, corner;
};


int main(){
	const int NumRows = GetFieldHeight();
  	const int NumCols = GetFieldWidth();
  	if (MyNodeId() == 0){
      Cell cols[NumRows][NumberOfNodes()-1];
      for(int instancja=1; instancja<NumberOfNodes(); ++instancja){
        Receive(instancja);
        for(int j=0; j<NumRows; j++){
          cols[j][instancja-1].left = GetInt(instancja);
          cols[j][instancja-1].corner = GetInt(instancja);
          cols[j][instancja-1].down = GetInt(instancja);
        }
      }
      
      for(int instancja=2; instancja<NumberOfNodes(); ++instancja){
        for(int j=0; j<NumRows; j++){
          int temp = NumCols * (instancja) / (NumberOfNodes() - 1) - NumCols * (instancja-1) / (NumberOfNodes() - 1);
          if(cols[j][instancja].left == temp){
            cols[j][instancja].left += cols[j][instancja-1].left;
            if(j >= temp && cols[j][instancja].left == cols[j][instancja].down == cols[j][instancja].corner){
              cols[j][instancja].corner += cols[j-temp][instancja-1].corner;
            }      
          }
        }
      }

      for(int instancja=2; instancja<NumberOfNodes(); ++instancja){
        for(int j=0; j<NumRows; j++){
          PutInt(instancja, cols[j][instancja-1].left);
          PutInt(instancja, cols[j][instancja-1].corner);
          if((j+1) % 7500 == 0) Send(instancja);
        }
      }

      int answer=0;
      for(int instancja=1; instancja<NumberOfNodes(); ++instancja){
        Receive(instancja);
        answer += GetInt(instancja);
      }
      cout << answer <<"\n";

  	} else {
  		int start = NumCols * (MyNodeId() - 1) / (NumberOfNodes() - 1);
  		int end = NumCols * MyNodeId() / (NumberOfNodes() - 1);
  		int size = end - start;
  		
  		Cell cells[NumRows][size];
  		for(int i=0; i<NumRows; i++){
  			for(int j=start; j<end; j++){
  				cells[i][j].isUsable = IsUsableCell(i,j);
  			}
  		}
  		///
  		for(int i=0; i<NumRows; i++){
  			if(cells[i][0].isUsable) cells[i][0].left = cells[i][0].down = cells[i][0].corner = 1;
  			else{
          cells[i][0].left = cells[i][0].down = cells[i][0].corner = 0;
        }
  		}
  		for(int i=0; i<size; i++){
  			if(cells[0][i].isUsable) cells[0][i].left = cells[0][i].down = cells[0][i].corner = 1;
  			else cells[0][i].left = cells[0][i].down = cells[0][i].corner = 0;
  		}
  		for(int i=1; i<NumRows; i++){
  			for(int j=1; j<size; j++){
  				if(cells[i][j].isUsable){
  					cells[i][j].left = cells[i][j-1].left + 1;
  					cells[i][j].down = cells[i-1][j].down + 1;
  					if(cells[i][j-1].isUsable && cells[i-1][j].isUsable) cells[i][j].corner = cells[i-1][j-1].corner + 1;
  					else cells[i][j].corner = 1;
  				} else {
  					cells[i][j].left = cells[i][j].down = cells[i][j].corner = 0;
  				}
  			}
  		}
  		///
      for(int i=0; i<NumRows; i++){
        PutInt(0, cells[i][size-1].left);
        PutInt(0, cells[i][size-1].corner);
        PutInt(0, cells[i][size-1].down);
        if((i + 1) % 5000 == 0){
          Send(0);
        }
      }
      Cell col[NumRows];
      if(MyNodeId() > 1){
        Receive(0);
        for(int i=0; i<NumRows; i++){
          col[i].left = GetInt(0);
          col[i].corner = GetInt(0);
        }
      } else {
        for(int i=0; i<NumRows; i++){
          col[i].left = col[i].corner = col[i].down = 0;
        }
      }
      for(int i=0; i<NumRows; i++){
        if(cells[i][0].isUsable) {
          cells[i][0].left = col[i].left+1;
          cells[i][0].corner = col[i].corner+1;
        }
        else{
          cells[i][0].left = cells[i][0].down = cells[i][0].corner = 0;
        }
      }

      for(int i=1; i<NumRows; i++){
        for(int j=1; j<size; j++){
          if(cells[i][j].isUsable){
            cells[i][j].left = cells[i][j-1].left + 1;
            cells[i][j].down = cells[i-1][j].down + 1;
            if(cells[i][j-1].isUsable && cells[i-1][j].isUsable) cells[i][j].corner = cells[i-1][j-1].corner + 1;
            else cells[i][j].corner = 1;
          } else {
            cells[i][j].left = cells[i][j].down = cells[i][j].corner = 0;
          }
        }
      }      

  		int answer=0;
  		for(int i=0; i<NumRows; i++){
  			for(int j=0; j<size; j++){
  				if(cells[i][j].isUsable) answer+=(cells[i][j].left + cells[i][j].down + cells[i][j].corner - 2);
  			}
  		}
      PutInt(0, answer);
      Send(0);
  	}
}