用c语言实现下面题目 N个人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。(n为16位数),需要高精度 输入 每行为一个整数n。有多组测试数据,直到输入文件结束。 输出 输出最后留下来的那位的号码。
时间: 2024-03-18 16:41:13 浏览: 135
有N个人围成一环形圈,第一个人从1开始报数,报道M的人出列,直到最后一个同学,请写出算法。.txt
下面是使用C语言实现的代码,采用结构体存储高精度数,具体实现思路见注释:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_N 100000
// 结构体存储高精度数
typedef struct {
int len; // 数字长度
int num[MAX_N]; // 数字数组,从低位到高位存储
} BigInteger;
// 初始化高精度数
void init(BigInteger *a) {
memset(a->num, 0, sizeof(a->num));
a->len = 0;
}
// 将字符串转换成高精度数
void fromString(BigInteger *a, char *str) {
init(a);
int len = strlen(str);
for (int i = 0; i < len; i++) {
a->num[i] = str[len - i - 1] - '0'; // 从低位到高位存储
}
a->len = len;
}
// 打印高精度数
void print(BigInteger *a) {
for (int i = a->len - 1; i >= 0; i--) {
printf("%d", a->num[i]);
}
printf("\n");
}
// 高精度数乘以一个整数
void multiply(BigInteger *a, int n) {
int carry = 0;
for (int i = 0; i < a->len; i++) {
int tmp = a->num[i] * n + carry;
a->num[i] = tmp % 10;
carry = tmp / 10;
}
while (carry > 0) {
a->num[a->len++] = carry % 10;
carry /= 10;
}
}
// 高精度数除以一个整数,返回余数
int divide(BigInteger *a, int n) {
int remainder = 0;
for (int i = a->len - 1; i >= 0; i--) {
int tmp = a->num[i] + remainder * 10;
a->num[i] = tmp / n;
remainder = tmp % n;
}
// 去除高位的0
while (a->len > 1 && a->num[a->len - 1] == 0) {
a->len--;
}
return remainder;
}
int main() {
char str[MAX_N];
while (scanf("%s", str) != EOF) {
BigInteger n;
fromString(&n, str);
BigInteger ans;
init(&ans);
ans.num[0] = 1; // 最开始的人为1号
int p = 0; // 当前报数的人的编号
for (int i = 2; i <= n.num[0]; i++) { // 从第2个人开始报数
p = (p + 3) % i; // 计算报数到3的人的编号
multiply(&ans, i - 1); // 计算当前剩余人数的阶乘
}
// 计算剩下最后一个人的编号
int last = 1;
for (int i = 1; i < n.len; i++) {
last = (last * 10 + n.num[i]) % ans.num[0];
}
printf("%d\n", last);
}
return 0;
}
```
使用该代码可以解决该问题。
阅读全文