糊涂的教授
题目链接:None
题目大意
有一些矩阵,然后又有一些数字,你要把数字和矩阵一一对应,使得数字在对于的矩阵里面。
如果有多重对应方法或无法对于就输出 None,否则输出对应方法。
思路
它是有点拓扑的感觉,反正你就不停地到能直接对应的关系。
(一个点只在一个矩阵里面或一个矩阵里面只有一个点)
然后就一直模拟。
(不过后来说上面的两种关系只用挑一种做就可以了,因为另一种其实就是反方向做)
代码
#include<cstdio>
using namespace std;
int n, x1[31], y1[31], x2[31], y2[31], x, y;
int have_point[31][31], in_board[31][31];
int real_have[31], real_in[31], dy[31];
bool do_point[31], do_board[31];
int main() {
// freopen("jiaoshou.in", "r", stdin);
// freopen("jiaoshou.out", "w", stdout);
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d %d %d %d", &x1[i], &x2[i], &y1[i], &y2[i]);
}
for (int i = 1; i <= n; i++) {//记录一个点在以多个板里面,一个板里面有多少个点
scanf("%d %d", &x, &y);
for (int j = 1; j <= n; j++) {
if (x >= x1[j] && x <= x2[j] && y >= y1[j] && y <= y2[j]) {
have_point[j][++have_point[j][0]] = i;
in_board[i][++in_board[i][0]] = j;
}
}
if (!in_board[i][0]) {
printf("None");
return 0;
}
}
for (int i = 1; i <= n; i++) {
real_have[i] = have_point[i][0];
real_in[i] = in_board[i][0];
}
for (int times = 1; times <= n; times++) {
bool yes = 0;
int cho = -1;
for (int i = 1; i <= n; i++)
if (!do_board[i]) {//找板里面只有一个点的
if (real_have[i] == 0) {//这个板里面没有点,不能一一对应
printf("None");
return 0;
}
if (real_have[i] == 1) {
yes = 1;
cho = i;
}
}
if (yes) {
for (int i = 1; i <= n; i++)
if (!do_point[i]) {
if (real_in[i] == 0) {//先确认没有点不在板里面
printf("None");
return 0;
}
}
do_board[cho] = 1;
for (int i = 1; i <= have_point[cho][0]; i++)//将对应的板和点抹去
if (!do_point[have_point[cho][i]]) {
do_point[have_point[cho][i]] = 1;
dy[cho] = have_point[cho][i];
for (int j = 1; j <= in_board[have_point[cho][i]][0]; j++)
if (!do_board[in_board[have_point[cho][i]][j]]) real_have[in_board[have_point[cho][i]][j]]--;
break;
}
}
if (!yes) {
for (int i = 1; i <= n; i++)
if (!do_point[i]) {//找点只在一个板里面的
if (real_in[i] == 0) {//点不在任何板里面,不能一一对应
printf("None");
return 0;
}
if (real_in[i] == 1) {
yes = 1;
cho = i;
}
}
if (yes) {
do_point[cho] = 1;
for (int i = 1; i <= in_board[cho][0]; i++)//抹去板和点
if (!do_board[in_board[cho][i]]) {
do_board[in_board[cho][i]] = 1;
dy[in_board[cho][i]] = cho;
for (int j = 1; j <= have_point[in_board[cho][i]][0]; j++)
if (!do_point[have_point[in_board[cho][i]][j]]) real_in[have_point[in_board[cho][i]][j]]--;
break;
}
}
}
if (!yes) {//找不到能继续确定的
printf("None");
return 0;
}
}
for (int i = 1; i <= n; i++) {//输出
printf("%c %d\n", i + 'A' - 1, dy[i]);
}
fclose(stdin);
fclose(stdout);
return 0;
}