2022.1.4 大一寒训题解

· · 个人记录

Problem A.开关灯

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#define cinios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
using namespace std;

const int N = 5010;
int n, m, k, T, S, D;
bool st[N];//布尔类型,只有0和1值,即假和真
//在 main 函数外初始化布尔变量,全部都会初始化为false

int main() {
    cinios;

    cin >> n >> m;
    //n 是灯数,m 是人数

    //定义true是开着灯,false是关着灯
    for (int i = 1; i <= n; i++)st[i] = true;//初始打开所有灯

    for (int i = 1; i <= m; i++)//枚举每个人
        for (int j = 1; j <= n; j++)//每个人对全部的灯做(相反的)开关处理
            if (j >= i && j % i == 0) {
                //注意,是 倍数 才操作,当前人操作的灯的编号要 大于等于 自己编号
                //用取余判断倍数

                if (!st[j])st[j] = true;//置换
                else st[j] = false;
            }

    int cnt = 0;
    for (int i = 1; i <= n; i++)
        if (!st[i]) { //输出关闭着的灯的编号
            if (!cnt)cout << i;
            else cout << "," << i;
            cnt++;
        }

    return 0;
}

Problem B.The New Year: Meeting Friends

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#define cinios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
using namespace std;

const int N = 5010;
int n, m, k, T, S, D;

int main() {
    cinios;

    int a, b, c;
    cin >> a >> b >> c;

    //题意要求找直线上离a b c三点最近的一个点
    //显然这个点只会在三个点之间

    int mx = max({ a,b,c }), mi = min({ a,b,c });
    //c++的取最大值最小值函数,取两个是max(a,b),若取多个变量就加括号

    int mii = 10000000;
    for (int i = mi; i <= mx; i++)//数据很小,确定边界后暴力枚举
        mii = min(mii, abs(a - i) + abs(b - i) + abs(c - i));
        //abs是取绝对值函数

    cout << mii;

    return 0;
}

Problem C.救援

两种写法:

用数组:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<math.h>
#define cinios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
using namespace std;

const int N = 510;
int n, m, k, T, S, D;
double x[N], y[N], r[N];//注意类型

double dist(double x1, double y1, double x2, double y2) {
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

int main() {
    cinios;

    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> x[i] >> y[i] >> r[i];//全部用数组存

    double t = 0;

    for (int i = 0; i < n; i++)
        t += (1.5 * r[i]) + (dist(0, 0, x[i], y[i]) / 50 * 2);

    //最后注意一下向上取整,意味着结果是个整数
    //相当于 +1 后向下取整
    int ans = ceil(t);
    cout << ans;

    return 0;
}

用结构体:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<math.h>
#define cinios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
using namespace std;

const int N = 510;
int n, m, k, T, S, D;
struct node
{
    double x, y;
    int r;
}nod[N];

double dist(node a, node b) {
    //传入的变量类型不是普通的int,因为要存x轴和y轴所以用了 node 类型

    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
    //解读:
    //开根号((a点x轴-b点x轴)的平方 +(a点y轴-b点y轴)的平方))
    //就是个简单数学计算
}

int main() {
    cinios;

    cin >> n;
    for (int i = 0; i < n; i++) {
        double a, b;//该点坐标
        int r;//该点有多少人
        cin >> a >> b >> r;
        nod[i] = { a,b,r };//全部存到结构体数组里
    }

    double t = 0;
    nod[n] = { 0,0 };//大本营的坐标

    for (int i = 0; i < n; i++)
        t += (1.5 * nod[i].r) + (dist(nod[n], nod[i]) / 50 * 2);
        //人上下船花的时间是 (1 + 0.5)*人数
        //然后就是大本营到该点的距离上耗时,注意船是要 跑来回 的
        //用 dist 函数求一下平面直角坐标系中两点间距离

    //最后注意一下向上取整,意味着结果是个整数
    //相当于 +1 后向下取整
    int ans = ceil(t);
    cout << ans;

    return 0;
}