2022.1.4 大一寒训题解
Chan_shang · · 个人记录
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;
}