#define MAX 131072 //存储石砖信息数量的最大值,同时代替Inf的使用 #include<stdio.h> #include<stdlib.h> typedefstructStoneInfo { int id; //石砖的id int w; //石砖的宽 int h; //石砖的高 int is_used; //该石砖是否已经切出 }StoneInfo; StoneInfo S[MAX]; int used_area = 0, top = 0, used_h = 0; //已经切出的石砖总面积,未切过的第一块石砖位置,已使用的高度 int n, num = 0; //石砖总数,目前切出的石板个数
intHeightCompare(StoneInfo* a, StoneInfo* b)//比较石砖高度时调用的函数 { if (b->h - a->h)return b->h - a->h; elsereturn b->w - a->w; } voidStoneCut(int w, int h)//石板切割函数 { if (h == 0 || w == 0)return; //待切石板的宽或高为0时退出函数 int i = top; if (h == MAX) //开辟新一块石板进行切割 { printf("从第%d块石板中切下的石砖id:%d ", ++num, S[i].id); S[i].is_used++; //该石砖已切出 used_h += S[i].h; //开辟相同高度的石板 used_area += S[i].w * S[i].h; //切出面积增加 printf("%d ", S[i].id); //输出该切出石砖的id StoneCut(w - S[i].w, S[i].h); //对剩余部分进行递归 while (S[top].is_used)top++; //使top指向未切过的第一块石砖的位置 printf("\n"); return; } while ((S[i].h > h || S[i].w > w || S[i].is_used) && i < n)i++; //找到可切且未切过的石砖 if (i < n) { S[i].is_used++; used_area += S[i].w * S[i].h; printf("%d ", S[i].id); StoneCut(w - S[i].w, h); StoneCut(S[i].w, h - S[i].h); while (S[top].is_used)top++; } return; }
intmain() { int W, i; scanf("%d%d", &n, &W); for (i = 0; i < n; i++) { scanf("%d%d%d", &S[i].id, &S[i].w, &S[i].h); //石砖数据 S[i].is_used = 0; //参数初始化 } qsort(S, n, sizeof(StoneInfo), HeightCompare); //按高度进行快速排序 while (top < n) //还有石砖未切出 StoneCut(W, MAX); printf("已使用的石板总高度为:%d\n所有切出的石砖总面积为:%d\n", used_h, used_area); double Used_Area = used_area, Total_Area = W * used_h; //转化为浮点数以进行利用率的运算 printf("计算得利用率为:%lf%%", Used_Area / Total_Area * 100); return0; }