pta模拟赛6-10(7-6 约瑟夫环、7-7 猴子选大王[加强版]、7-8 计算n!(n要能大于13)、7-9 哪两个点之间的距离最近、7-10 哪两个点之间的距离最近[增强版])

 7-6 约瑟夫环

N个人围成一圈顺序编号,从1号开始按1、2、3......顺序报数,报p者退出圈外,其余的人再从1、2、3开始报数,报p的人再退出圈外,以此类推。
请按退出顺序输出每个退出人的原序号。

输入格式:

输入只有一行,包括一个整数N(1<=N<=3000)及一个整数p(1<=p<=5000)。

输出格式:

按退出顺序输出每个退出人的原序号,数据间以一个空格分隔,但行尾无空格。

输入样例:

在这里给出一组输入。例如:

7 3

输出样例:

3 6 2 7 5 1 4
代码展示
#include<bits/stdc++.h>
using namespace std;
int a[10000]={0};//将未淘汰的人员赋初值,若淘汰则为1
int main(){
    int n,p;
    int cnt=0,k=0,i=0;
    //cnt淘汰人数
    //k计数器,计算是否数到p
    //i人员编号,数组下标
    cin>>n>>p;
    while(cnt!=n)
    {//是否淘汰了n个人
        i++;//人员编号
        if(i>n) i=1;
        if(a[i]==0){//判断是否被淘汰
            k++;
            if(k==p){//判断是否数到p
                a[i]=1;
                cnt++;
                if(cnt<n)
                {
                    cout<<i<<" ";
                }
                else cout<<i;
                k=0;
            }
        }
    }
}

 

7-7 猴子选大王[加强版]、

一群猴子要选大王,遴选的方法是:让M只候选猴子围成一圈,从某位置起顺序编号为0∼M−1号。从第0号开始报N个数字,每轮从0报到N−1,凡报到N−1的猴子即退出候选,接着又从紧邻的下一只猴子开始同样的报数。如此不断循环,最后剩下的一只猴子就选为猴王。问猴王是原来第几号猴子?

输入格式:

在一行中输入两个整数M和N,分别代表猴群数量和报数数。整数与整数之间用空格间隔。

输出格式:

在一行中输出一个数,表示当选猴子编号。

输入样例:

9 2

输出样例:

2
代码展示
#include <stdio.h>
int main() 
{
    int n, m, result = 0;
    scanf("%d %d", &n, &m);
    for (int z = 2; z <= n; z++) 
    {
        result = (result + m) % z;
    }
    printf("%d\n", result);
    return 0;
}

7-8 计算n!(n要能大于13)

编写程序,求n!(n的值要能大于13),其结果用一个不超过64位的十进制数输出。

输入格式:

输入一个非负整数,其值介于2到49之间的数。

输出格式:

对每一个输入的整数,在一行中输出相应的阶乘值,输出结果的高位用0填充。

输入样例1:

在这里给出一组输入。例如:

7

输出样例1:

在这里给出相应的输出。例如:

5040

输入样例2:

在这里给出一组输入。例如:

49
代码展示
#include<stdio.h>
#include<string.h>
#define MAXLEN 10000
int main()
{
    int n, i, j, up, tmp;
    char arr[MAXLEN+1] = {1};
    scanf("%d",&n);
    for(i = 2;i <= n;i++)
    {
        for(up = 0,j = 0;j <= MAXLEN;j++)
        {
            tmp = arr[j] * i + up;
            arr[j] = tmp % 10;
            up = tmp / 10;
        }
    }
     for(i = MAXLEN;i>=0;i--)
     if(arr[i]!=0)
    for(i;i>=0;i--)
    printf("%d",arr[i]);
    return 0;
}

7-9 哪两个点之间的距离最近

设P={(x1​,y1​),(x2​,y2​),⋯,(xn​,yn​)}是平面上散列的n个点的集合。请编写程序找出集合中距离最近的点对。严格地说,相同距离的最近点对可能不止一对,为了简单期间只找出第一对最近点对即可。

输入格式:

输入第一行给出一个正整数n,表示平面上的点数。随后n行,每行给出一个实数对,每个实数对表示一个点的纵横坐标值,其中第1数表示横坐标,第2数表示纵坐标。

输出格式:

输出最近点对中两个点的坐标和它们之间的距离。如果 x1+y1<=x2+y2则按
  (x1,y1),(x2,y2),miniDist=Distance
输出结果,否则按
  (x2,y2),(x1,y1),miniDist=Distance
输出结果。
  其中x1,y1,x2,y2是保留两位小数的实数,Distance是保留3位小数的实数

输入样例:

5
1.00 1.00
2.00 0.00
0.00 2.00
0.50 0.60
-1.00 2.00

输出样例:

(0.50,0.60),(1.00,1.00),miniDist=0.640
代码展示
#include <stdio.h>
#include <math.h>
double sum(double x1, double x2, double y1, double y2)
{
    return sqrt(pow((x1 - x2), 2) + pow((y1 - y2), 2));
}
int a, b;
double miniDist = 1000000;
int main()
{
    int n;
    scanf("%d", &n);
    double x[n+1];
    double y[n+1];
    for (int i = 0; i < n; ++i)
    {
        scanf("%lf %lf", &x[i], &y[i]);
    }
    for (int i = 0; i < n-1 ; ++i)
    {
        for (int j = i + 1; j < n; ++j)
        {
            if (sum(x[i], x[j], y[i], y[j]) < miniDist)
            {
                miniDist = sum(x[i], x[j], y[i], y[j]);
                a = i;
                b = j;
            }
        }
    }
    if ((x[a] + y[a]) > (x[b] + y[b]))
    {
        int t = a;
        a = b;
        b = t;
    }
    printf("(%.2f,%.2f),(%.2f,%.2f),miniDist=%.3f", x[a], y[a], x[b], y[b], miniDist);
}

7-10 哪两个点之间的距离最近[增强版]

设P={(x1​,y1​),(x2​,y2​),⋯,(xn​,yn​)}是平面上散列的n个点的集合。请编写程序找出集合中距离最近的点对。严格地说,相同距离的最近点对可能不止一对,为了简单期间只找出第一对最近点对即可。题目保证输入的所有数据均按照横坐标值进行升序排列。

输入格式:

输入第一行给出一个正整数n,表示平面上点的数数量。随后n行,每行给出一个实数对,每个实数对表示一个点的坐标值,其中第1数表示横坐标,第2数表示纵坐标。

输出格式:

输出最近点对中两个点的坐标和它们之间的距离。如果 x1+y1<=x2+y2则按
  (x1,y1),(x2,y2),miniDist=Distance
输出结果,否则按
  (x2,y2),(x1,y1),miniDist=Distance
输出结果。
  其中x1,y1,x2,y2是保留两位小数的实数,Distance是保留3位小数的实数

输入样例:

5
-1.00 2.00
0.00 2.00
0.50 0.60
1.00 1.00
2.00 0.00

输出样例:

(0.50,0.60),(1.00,1.00),miniDist=0.640
代码展示
#include <stdio.h>
#include <math.h>

#define N 1000010
#define INF 1e18

struct point 
{
    double x, y;
} p[N];

int n, s1, s2;
double sur = 1e18;
int t[N];

double dis(int x, int y) 
{
    return sqrt(pow((p[x].x - p[y].x), 2) + pow((p[x].y - p[y].y), 2));
}

double min(double a, double b) 
{
    return a < b ? a : b;
}

double run(int l, int r) 
{
    if(l == r) 
        return INF;
    int mid = (l + r) >> 1;
    double d = min(run(l, mid), run(mid + 1, r));
    int temp = 0;
    for (int i = l; i <= r; ++i) 
    {
        if (dis(i, mid) < d) 
            t[++temp] = i;
    }
    for (int i = 1; i <= temp; ++i) 
    {
        for (int j = i + 1; j <= temp; ++j) 
        {
            double dist = dis(t[i], t[j]);
            d = min(d, dist);
            if (dist < sur) 
            {
                sur = dist;
                s1 = t[i];
                s2 = t[j];
            }
        }
    }
    return d;
}

int main() 
{
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) 
    {
        scanf("%lf %lf", &p[i].x, &p[i].y);
    }
    double ans = run(1, n);
    if (p[s1].x + p[s1].y > p[s2].x + p[s2].y) 
    {
        int temp = s1;
        s1 = s2;
        s2 = temp;
    }
    printf("(%.2f,%.2f),(%.2f,%.2f),miniDist=%.3f", p[s1].x, p[s1].y, p[s2].x, p[s2].y, ans);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不懂c语言的小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值