题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=79
解题报告:
思路简单,写法太难。
#include <stdio.h> #include <stdlib.h> #include <string.h> ///x,y的增量 int dx[4] = {1,0,-1,0}; int dy[4] = {0,1,0,-1}; int queue[501]; int used[500]; ///使用数组piece表示拼图的每一片的信息 struct { int id; ///这一片,他的相邻的片的编号 int side; ///这一片,他的相邻片的邻边的编号 }piece[500][4]; ///使用数组pos保存拼图的位置信息,输出结果 struct position{ int x, y; ///坐标 int id; ///卡片的编号 int side; ///下底的编号 }pos[500]; int compare(const void *a,const void *b) { int c; if((c=(((struct position*)a)->x-((struct position*)b)->x))!=0) return(c); return((((struct position*)a)->y-((struct position*)b)->y)); } int main() { int n, k; ///卡片的数量和k个卡片的信息量 int i; int cases = 1; while(scanf("%d", &n) && n) { scanf("%d", &k); memset(piece, 255, sizeof(piece)); memset(used, 0, sizeof(used)); int a, b, c, d; for(i=0; i<k; i++) { scanf("%d%d%d%d", &a, &b, &c, &d); piece[a][b].id = c; piece[a][b].side = d; piece[c][d].id = a; piece[c][d].side = b; } ///编号初始化 for(i=0; i<n; i++) pos[i].id = i; pos[0].x = 0; pos[0].y = 0; pos[0].side = 0; used[0] = 1; queue[0] = 0; int first = 0; ///队列的头部位置 int count = 0; ///队列的尾部位置 ///队列还没有搜索完毕 while (first<=count) { ///搜索当前节点 a = queue[first]; ///编号 int x0 = pos[a].x; int y0 = pos[a].y; d = pos[a].side; int number; ///相邻卡片的编号 ///对相邻卡片的4边搜索 for(i=0; i<4; i++) { ///输入数据有卡片的信息 if((number=piece[a][i].id)>=0) ///该卡片还没有搜过 if(used[number]==0) { b = piece[a][i].side; used[number] = 1; ///计算相邻卡片的位置和底边的信息 ///x&3相当于(x+4)%4 pos[number].x = x0+dx[(i-d)&3]; pos[number].y = y0+dy[(i-d)&3]; pos[number].side = ((b-i+d+2)&3); ///该卡片进入队列 queue[++count] = number; } } first++; ///搜索下一个节点 } qsort(pos, n, sizeof(position), compare); a = pos[0].x; b = pos[0].y; printf("Instance %d:\n",cases++); for(i=0; i<n; i++) printf("%5d%5d%6d%2d\n", pos[i].x-a, pos[i].y-b, pos[i].id, pos[i].side); } return 0; }
时间: 2024-10-07 05:06:50