【ACM Greater New York 2017】 C. Capsules

At some point or another, most computer science students have written a standard Sudoku solving program. This is yet another "put numbers in a grid" puzzle.

Numbers are placed in the grid so that each outlined region contains the numbers 11 to nn, where nn is the number of squares in the region. The same number can never touch itself, not even diagonally.

For this problem, you will write a program that takes as input an incomplete puzzle grid and outputs the puzzle solution grid.

Input Format

The first line of input contains a single decimal integer P(1 \le P \le 100)P(1≤P≤100), which is the number of data sets that follow. Each data set should be processed identically and independently.

Each data set starts with a line containing the data set number K(1 \le K \le 100)K(1≤K≤100), the number of rows in the input grid R(1 \le R \le 7)R(1≤R≤7), and the number of columns in the input grid C(1 \le C \le 7)C(1≤C≤7), separated by spaces. The next RR lines contain a representation of the incomplete input grid, one row per line. The value in each cell is represented by either the digit already in that cell or a '-' for an initially empty cell.

This grid is followed by a description of the separate regions in the grid. The first of these lines specifies the total number of regions. This is followed by one line for each region that specifies the cells contained in that region. Each region description consists of a decimal number NN, specifying the number of cells in the region, followed by NN cell descriptions separated by spaces. Each cell description consists of a left parenthesis, followed the cell's row index, followed by a comma, followed by the cell's row number, followed by a right parenthesis.

Output Format

For each data set, the output consists of the data set number, KK, on a line by itself.

This is followed by RR lines containing CC digits (separated by single spaces) showing the solution grid for the corresponding input data set.

样例输入

2
1 3 5
- - - - -
- - - - -
4 - - - 1
5
1 (1,1)
2 (1,2) (1,3)
5 (2,1) (2,2) (3,1) (3,2) (3,3)
4 (2,3) (2,4) (1,4) (1,5)
3 (3,4) (3,5) (2,5)
2 7 7
- - - - - - -
4 - - - - 5 -
- - - - - - -
- - - 3 - - -
- - - - - - -
- - - - - - -
- - - - - - -
14
5 (1,1) (2,1) (3,1) (2,2) (2,3)
4 (2,4) (1,2) (1,3) (1,4)
2 (1,5) (1,6)
1 (1,7)
4 (4,1) (5,1) (6,1) (5,2)
1 (7,1)
4 (3,2) (4,2) (4,3) (5,3)
3 (7,3) (7,2) (6,2)
4 (6,3) (6,4) (7,4) (7,5)
6 (2,5) (3,5) (4,5) (3,6) (2,6) (2,7)
4 (3,7) (4,7) (4,6) (5,6)
1 (5,7)
5 (7,7) (7,6) (6,7) (6,6) (6,5)
5 (3,3) (3,4) (4,4) (5,4) (5,5)

样例输出

1
1 2 1 2 1
3 5 3 4 3
4 2 1 2 1
2
3 1 4 2 1 2 1
4 2 5 3 6 5 4
1 3 1 4 2 3 1
2 4 2 3 1 4 2
1 3 1 5 2 3 1
4 2 4 3 4 5 2
1 3 1 2 1 3 1

题目大意:

多组数据,每组数据先输入一行,数组组号k,矩阵n行m列;第二行输入初始矩阵,数字方块不能改变,-方块用于填数;将矩阵分成了p块区域;每块区域先输入该块区域的方格数num,再输入num个坐标为同一块区域里的。输出数据组号,再输出填好数的矩阵,要求矩阵里的某个方格其四周八个方向都不能与之相等,并且同一块区域里的方格填入的数不能重复。

 

对地图进行划分局部区域,同时又与真实填数Map[maxn][maxn]相对应:
可以用结构体数组进行标记,方格总个数为结构体数组的大小:
struct ditu {
  int x, y, sum, knum;//x,y记录Map地图的坐标(dfs搜索时是从左到右,从上到下,因为x,y记录也是如此;sum表示该点所在的块总共有sum个方格;knum进行区域(块)编号(可以从0开始),两个点即使sum相同也可能不是同一个区域(块)的(区域编号可能不同))
}d[50];

暴搜一发:

#include<bits/stdc++.h>
using namespace std;
int Map[7][7];
int flag, k, n, m, tot, p, num, xx, yy;
struct ditu {
  int x, y, sum, knum;
}d[50];
int check(int x, int y, int k, int pp) {
  for(int i = 0; i < tot; i++)
    if(d[i].knum == pp && Map[d[i].x][d[i].y] == k) return 0;
  if(x-1 >= 0) {
    if(Map[x-1][y] == k) return 0;
    if(y-1 >= 0 && Map[x-1][y-1] == k) return 0;
    if(y+1 < m && Map[x-1][y+1] == k) return 0;
  }
  if(x+1 < n) {
    if(Map[x+1][y] == k) return 0;
    if(y-1 >= 0 && Map[x+1][y-1] == k) return 0;
    if(y+1 < m && Map[x+1][y+1] == k) return 0;
  } 
  if(y-1 >= 0 && Map[x][y-1] == k) return 0;
  if(y+1 < m && Map[x][y+1] == k) return 0;
  return 1;
}
void dfs(int x, int y) {
  if(flag) return;
  if(x == n && y == 0) {
    for(int i = 0; i < n; i++) {
      for(int j = 0; j < m; j++) {
        if(j == 0) cout << Map[i][j];
        else
          cout << " " << Map[i][j];
      }
      cout << endl;
    }
    flag = 1;
    return;
  }
  if(y >= m) dfs(x+1, 0);
  else {
    if(Map[x][y]) dfs(x, y+1);
    if(!Map[x][y]) {
      int cc, pp;
      for(int l = 0; l < tot; l++) {
        if(d[l].x == x && d[l].y == y) {
          cc = d[l].sum;
          pp = d[l].knum;
          break;
        }
      }
      for(int k = 1; k <= cc; k++) {
        if(check(x, y, k, pp)) {
          Map[x][y] = k;
          dfs(x, y+1);
          Map[x][y] = 0;
        } 
      }
    }
  }
}
int main() {
  int t;
  cin >> t;
  while(t--) {
    memset(Map, 0, sizeof(Map));
    memset(d, 0, sizeof(d));
    char ch;
    flag = 0;
    int numn;
    cin >> k >> n >> m;
    tot = 0;
    for(int i = 0; i < n; i++) {
      for(int j = 0; j < m; j++) {
        d[tot].x = i;
        d[tot].y = j;
        d[tot].sum = 0;
        d[tot].knum = 0;
        tot++;
        cin >> ch;
        if(ch >= '0' && ch <= '9') Map[i][j] = (int)(ch-'0');
        else
          Map[i][j] = 0;
      }
      getchar();
    }
    cin >> p;
    for(int i = 0; i < p; i++) {
      cin >> num;
      for(int j = 0; j < num; j++) {
        getchar();
        if(j == 0) scanf("(%d,%d)", &xx, &yy);
        else
          scanf("(%d,%d)", &xx, &yy);
        for(int l = 0; l < tot; l++) {
          if(d[l].x == xx-1 && d[l].y == yy-1) {
            d[l].sum = num;
            d[l].knum = i;
            break;
          }
        }
      }
    }
    cout << k << endl;
    dfs(0, 0);
  }
  return 0;
} 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值