#include <stdio.h>
#include <stdlib.h>
struct tableMove{
int src;
int dst;
};
int getMax(int a, int b) {
return a >= b ? a : b;
}
int getMin(int a, int b) {
return a < b ? a : b;
}
void tableMoveswap(tableMove * moveA, tableMove * moveB) {
int tmpSrc = moveA->src;
int tmpDst = moveA->dst;
moveA->src = moveB->src;
moveA->dst = moveB->dst;
moveB->src = tmpSrc;
moveB->dst = tmpDst;
}
void sortTableMoveArrayAsDst(tableMove * tabelMoveArray, int length) {
for (int i = 0; i < length - 1; i++) {
bool exchanged = false;
for (int j = 0; j <= (length - i -1) - 1; j++) {
if (tabelMoveArray[j].dst > tabelMoveArray[j+1].dst) {
tableMoveswap(&tabelMoveArray[j], &tabelMoveArray[j+1]);
exchanged = true;
}
}
if (exchanged == false) {
break;
}
}
}
void sortTableMoveArrayAsSrc(tableMove * tabelMoveArray, int length) {
for (int i = 0; i < length - 1; i++) {
bool exchanged = false;
for (int j = 0; j <= (length - i -1) - 1; j++) {
if (tabelMoveArray[j].src > tabelMoveArray[j+1].src) {
tableMoveswap(&tabelMoveArray[j], &tabelMoveArray[j+1]);
exchanged = true;
}
}
if (exchanged == false) {
break;
}
}
}
int getMinMoveTime(tableMove * tabelMoveArray, int tabelMoveTime) {
sortTableMoveArrayAsSrc(tabelMoveArray, tabelMoveTime);
int moveTime = 0;
int SUM = tabelMoveTime;
while(1) {
int dst = -1;
for (int i = 0; i < tabelMoveTime; i++) {
if (tabelMoveArray[i].dst > 0 && dst == -1) {
dst = tabelMoveArray[i].dst;
tabelMoveArray[i].dst = -1;
SUM--;
} else if (tabelMoveArray[i].dst > 0) {
if (tabelMoveArray[i].src > dst) {
dst = tabelMoveArray[i].dst;
tabelMoveArray[i].dst = -1;
SUM--;
}
}
}
moveTime++;
if (SUM == 0) {
break;
}
}
return moveTime;
}
void runOneCase() {
int tabelMoveTime = 0;
scanf("%d", &tabelMoveTime);
tableMove * tabelMoveArray= (tableMove *)malloc(sizeof(tableMove) * tabelMoveTime);
for (int i = 0; i < tabelMoveTime; i++) {
int src, dst = 0;
scanf("%d %d", &src, &dst);
if (src % 2 == 1) {
src++;
}
if (dst % 2 == 1) {
dst++;
}
tabelMoveArray[i].src = getMin(src, dst);
tabelMoveArray[i].dst = getMax(src, dst);
}
int minMoveTime = getMinMoveTime(tabelMoveArray, tabelMoveTime);
printf("%d\n", minMoveTime * 10);
free(tabelMoveArray);
tabelMoveArray = NULL;
}
int main() {
int testCaseNum = 0;
scanf("%d", &testCaseNum);
for (int i = 0; i < testCaseNum; i++) {
runOneCase();
}
#include <stdlib.h>
struct tableMove{
int src;
int dst;
};
int getMax(int a, int b) {
return a >= b ? a : b;
}
int getMin(int a, int b) {
return a < b ? a : b;
}
void tableMoveswap(tableMove * moveA, tableMove * moveB) {
int tmpSrc = moveA->src;
int tmpDst = moveA->dst;
moveA->src = moveB->src;
moveA->dst = moveB->dst;
moveB->src = tmpSrc;
moveB->dst = tmpDst;
}
void sortTableMoveArrayAsDst(tableMove * tabelMoveArray, int length) {
for (int i = 0; i < length - 1; i++) {
bool exchanged = false;
for (int j = 0; j <= (length - i -1) - 1; j++) {
if (tabelMoveArray[j].dst > tabelMoveArray[j+1].dst) {
tableMoveswap(&tabelMoveArray[j], &tabelMoveArray[j+1]);
exchanged = true;
}
}
if (exchanged == false) {
break;
}
}
}
void sortTableMoveArrayAsSrc(tableMove * tabelMoveArray, int length) {
for (int i = 0; i < length - 1; i++) {
bool exchanged = false;
for (int j = 0; j <= (length - i -1) - 1; j++) {
if (tabelMoveArray[j].src > tabelMoveArray[j+1].src) {
tableMoveswap(&tabelMoveArray[j], &tabelMoveArray[j+1]);
exchanged = true;
}
}
if (exchanged == false) {
break;
}
}
}
int getMinMoveTime(tableMove * tabelMoveArray, int tabelMoveTime) {
sortTableMoveArrayAsSrc(tabelMoveArray, tabelMoveTime);
int moveTime = 0;
int SUM = tabelMoveTime;
while(1) {
int dst = -1;
for (int i = 0; i < tabelMoveTime; i++) {
if (tabelMoveArray[i].dst > 0 && dst == -1) {
dst = tabelMoveArray[i].dst;
tabelMoveArray[i].dst = -1;
SUM--;
} else if (tabelMoveArray[i].dst > 0) {
if (tabelMoveArray[i].src > dst) {
dst = tabelMoveArray[i].dst;
tabelMoveArray[i].dst = -1;
SUM--;
}
}
}
moveTime++;
if (SUM == 0) {
break;
}
}
return moveTime;
}
void runOneCase() {
int tabelMoveTime = 0;
scanf("%d", &tabelMoveTime);
tableMove * tabelMoveArray= (tableMove *)malloc(sizeof(tableMove) * tabelMoveTime);
for (int i = 0; i < tabelMoveTime; i++) {
int src, dst = 0;
scanf("%d %d", &src, &dst);
if (src % 2 == 1) {
src++;
}
if (dst % 2 == 1) {
dst++;
}
tabelMoveArray[i].src = getMin(src, dst);
tabelMoveArray[i].dst = getMax(src, dst);
}
int minMoveTime = getMinMoveTime(tabelMoveArray, tabelMoveTime);
printf("%d\n", minMoveTime * 10);
free(tabelMoveArray);
tabelMoveArray = NULL;
}
int main() {
int testCaseNum = 0;
scanf("%d", &testCaseNum);
for (int i = 0; i < testCaseNum; i++) {
runOneCase();
}
}
用贪心法的版本,
看了discuss里的另一种解答才明白为何此题能算水题(回头写一下, 也要记住)。
疑问:
1. 按照 dst 进行排序得到的一直不对, 按照 src 就对了, 要好好看看贪心法了。
与算法导论中的贪心法实例的不同在于, 该题要求的是一个全局的最优(全部移动完所需的总次数),而实例一般求的是一次移动能移动最多的个数。
有很大的不同,上面按照src排序,再用传统贪心法,能得到答案,但是如何证明?