指定一个区间
[x,y],在一个存有n个整数的顺序表中删除处于该区间之中的数。要求时间复杂度小于O(n^2)。可以使用划分的算法来进行判断并删除。
代码如:void fun(SqList *L, int x, int y)
{int i = 0, j = L->length - 1;
while (i < j)
{// while (i < j)// {// if (L->data[i] >= x && L->data[i] <= y)// {// break;// }// else// {// i++;// }// } // 和下面的 while 等价while (i < j && (L->data[i] < x || L->data[i] > y))
{i++; //i 从左向右扫描,遇到在 [x,y] 区间的数停下
}// while (i < j)// {// if (L->data[j] < x || L->data[j] > y)// {// break;// }// else// {// j--;// }// } // 和下面的 while 等价while (i < j && L->data[j] >= x && L->data[j] <= y)
{j--; //j 从右向左扫描,遇到不在 [x,y] 区间的数停下
}swap(*&(L->data[i]), *&(L->data[j]));
}L->length = i;//i 扫描过的数均为不在 [x,y] 区间的数
}也可以直接使用删除的算法。
给定一个正整数,求和是该正整数的正整数序列。例如:6=1+2+3。
void fun(int n)
{int a = 0;
int *s = &a; // 用于取出循环计算结果
int flag = 0;
for (int i = n / 2; i > 0; i--) // 从 n/2 开始 i 向下遍历
{for (int c = i, sum = 0; sum < n; ++c) // 从 i 开始 c 向 n 遍历,一旦 sum 大于 n 则跳出循环
{sum = sum + c;
*s = sum;
}if (*s == n)
{for (int j = i, sum = 0; sum != *s; j++) // 输出正整数序列
{cout << j << "+";
sum = sum + j;
}cout <<char(8) <<"=" << *s << endl;//ASCII 中 8 是 backspace,用于删除循环输出的多余的加号,*s 输出计算结果,即 n
*s = 0;
flag += 1;
}}if (flag == 0)
{cout << "找不到" << endl;
}}由题目可知只要有输出,输出一定是等差数列,且和为。所以,考虑等差数列求和公式
由题, 为用户输入,;。所以,可以将原式转化为含 的不等式,即
配方可得 有上界,即
由此得到 的遍历范围。将 向下取整后在式(1)中按此范围遍历,验证求得的 是否是整数。若是,则直接按 和当前的 进行输出后继续循环;若否,则直接继续循环。
如此,算法复杂度为。
代码如下:void fun(int m)
{int n = 0,start = 0,end = 0,flag = 0;
double temp = 0.0;
for (n = sqrt(2.0 * double(m) + 0.25) - 0.5; n > 1; --n)
{temp = double(m) / n - double(n - 1) * 0.5f;
if (temp == int(temp))
{for (flag = 1,start = int(temp),end = start + n; start < end; start++)
{cout << start << '+';
}cout << char(8) << endl;
}}if (flag == 0)
{cout << "None." << endl;
}}