目录
约瑟夫环
题目描述:有n 个人围成一圈,顺序排号。从第1个人开始报数从1到3报数凡是报到3 的人退出圈子,问最后留下的是原来的第几号?
环形处理:依次遍历数据集的每个元素(每个人依次报号),直到遍历到最后一个元素时,便开始对数据集进行新一轮的遍历(最后一个人报完号后,再次轮到第一个人报号)。
处理方法1:i=(i+1)%n
cpp
int joseph(int n)
{
int* arr = (int*)malloc(n * sizeof(int));//标志数组
assert(arr != NULL);
if (arr == NULL)
return -1;//出错
int i;
for (i = 0; i < n; i++) {
arr[i] = 1;//1还在游戏,0退出游戏
}
int count = n;//还在参与游戏的人数
int tmp = 0;//报数器
i = 0;
while (count > 1) {
if (arr[i] == 1)//报数
{
tmp++;
if (tmp == 3)//退出
{
arr[i] = 0;
count--;
tmp = 0;
}
}
//i++//线性,错误,必须环形处理
i = (i + 1) % n;//环形
}
//找还在参与的人数
for (i = 0; i < n; i++) {
if (arr[i] == 1)
break;
}
free(arr);
return i + 1;
}
处理方法2:
- if-else语句判断
- 三目运算符i = (i == n - 1) ? 0 : i + 1;
cpp
int joseph(int n)
{
int* arr = (int*)malloc(n * sizeof(int));//标志数组
assert(arr != NULL);
if (arr == NULL)
return -1;//出错
int i;
for (i = 0; i < n; i++) {
arr[i] = 1;//1还在游戏,0退出游戏
}
int count = n;//还在参与游戏的人数
int tmp = 0;//报数器
i = 0;
while (count > 1) {
if (arr[i] == 1)//报数
{
tmp++;
if (tmp == 3)//退出
{
arr[i] = 0;
count--;
tmp = 0;
}
}
//if (i == n - 1)
// i = 0;
//else
// ++i;
i = (i == n - 1) ? 0 : i + 1;
}
//找还在参与的人数
for (i = 0; i < n; i++) {
if (arr[i] == 1)
break;
}
free(arr);
return i + 1;
}
魔方阵
输出奇数阶"魔方阵"。所谓魔方阵是指这样的方阵,它的每一行、每一列和对角线之和均相等。
例如,三阶魔方阵为:
奇数魔方阵的特点:
1.数字1放在第一行中间;
2下一个值放在前一个值的"上一行,后一列"(例如数字2,数字3);
3如果下一个位置已经有数据了,则放在前一个值的"下一行,同列"(例如数字4).
cpp
int** Cube(int n)
{
if (n % 2 != 1)
return NULL;
int** p = (int**)malloc(n * sizeof(int*));
assert(p != NULL);
for (int i = 0; i < n; i++)
{
p[i] = (int*)calloc(n,sizeof(int));
assert(p[i] != NULL);
}
int i = 0;
int j = n / 2;
p[i][j] = 1;
int tmp = 2;
while (tmp <=n*n)
{
if (p[(i + n - 1) % n][(j + 1) % n] == 0)
{
p[(i + n - 1) % n][(j + 1) % n] = tmp;
i = (i + n - 1) % n;
j = (j + 1) % n;
}
else
{
p[(i + 1) % n][j] = tmp;
i = (i + 1) % n;
}
tmp++;
}
return p;
}
int main() {
int** arr = Cube(3);
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
return 0;
}
总结:
环形处理向后移动:i=(i+1)%n
环形处理向前移动:i=(i-1+n)%n