/*负数左动,正数右动。大小表示质量,质量小的碰撞消失。求最后剩余行星*/
/*贪心:把一个复杂的过程变为多个相似的简单过程(从左往右,撞毁一个就停止前进【变简单】,回到最左边重新开始【相似多个过程】)*/
#include<iostream>
#include<cmath>
using namespace std;
void collision(int* data, int dataSize)
{
int n = 0;
while (1)//死循环
{
//为避免已经毁坏行星的干扰(0的干扰),用“指针”而不是遍历i与i+1
int pre = 0;
int next = 1;
while (next < dataSize) {
//分3种情况
//乘积小于0
if (data[pre] * data[next] < 0) {
if (data[pre] < 0) {//左边负右边正,运动方向相反,不撞
pre = next;
next++;
continue;//!!!还没有毁坏行星,避免后面被break跳出循环
}
if (abs(data[pre]) > abs(data[next])) {
data[next] = 0;
n++;
}
else if (abs(data[pre]) < abs(data[next])) {
data[pre] = 0;
n++;
}
else {
data[pre] = 0;
data[next] = 0;
n += 2;
}
break;
}
//乘积等于0
else if (data[pre] * data[next] == 0) {
if (data[pre] == 0) {
pre = next;
next++;
}
else if (data[next] == 0)
next++;
}
//乘积大于0
else {
pre = next;
next++;
}
}
if (next >= dataSize)
break;//直到最右边任然没有撞击,表明前面数轮已经全部撞击完毕,结束
}
for (int i = 0; i < dataSize; i++) {
if (data[i]) {
cout << data[i] << " ";
}
}
}
void main()
{
int data[] = { -9,1,2,-3,-9,5,-5,4,3,-1,-10 };
int dataSize = sizeof(data) / sizeof(data[0]);
collision(data, dataSize);
}
贪心--行星碰撞问题--C++
于 2023-09-09 14:06:45 首次发布