写在前面:本题解旨在帮助进行作业参考,为学习升华所用。登高自卑,戒骄戒躁。
第一题:快速公交BRT
思路分析:本题考察数组基本应用,强模拟的题目。
#include<iostream>
using namespace std;
typedef unsigned int ui;
int main() {
ui n, g, r;
cin >> n >> g >> r;
ui* t = new ui[n + 1]; //n个路口,n+1道路段,用数组t记录公交通过每段路口的时间
for (ui i = 0; i <= n; i++)cin >> t[i];
ui T;
cin >> T; //公交的辆数,即测试案例的数目
while (T--) {
ui q; //出发的时间
cin >>q;
ui res = q; //用res记录时间的推移
for (ui i = 0; i < n; i++) {
res += t[i]; //经过某路段之后的时间 亮绿灯亮红灯为一个循环节
if (res % (g + r) < g) res += 0; //res%(g+r)<g,模拟遇到绿灯的情境,不可=
else res = res / (g + r) * (g + r) + (g + r);//遇到红灯则推一个循环节
}
res += t[n];
cout << res << ' ';
}
delete[]t;
return 0;
}
第一题:用数组模拟好情景即可,后面会遇到很多强模拟的题目
第二题:小希的工作
依旧是强模拟的题目。模拟很考验对所学知识的理解,以及实际应用的能力。能把所学知识轻易应用于生活,是工具学科极大的魅力所在。
#include<iostream>
using namespace std;
typedef unsigned int ui;
int main() {
ui L, n, a;
cin >> n >> L >> a;
ui* qt = new ui[n]; //起始时间
ui* jt = new ui[n]; //结束时间
for (ui i = 0; i < n; i++) {
cin >> qt[i]; //客户来到的时间
ui tmp; //工作的时间
cin >> tmp;
jt[i] = qt[i]+tmp; //一段工作结束的时间
}
ui cnt = 0; //计数
cnt += qt[0] / a; //如果第一段工作开始时间大于放松时光a,cnt+1
cnt += (L - jt[n - 1]) / a; //同理,如果L-最晚的结束时间,cnt+1
for (ui i = 1; i <= n - 1; i++) {
cnt += (qt[i] - jt[i - 1]) / a; //逐次判断每段工作时间的间隔里,有多少段放松时光
}
cout << cnt << endl; //输出结果
delete[]qt;
delete[]jt; //动态数组,一定要删除
return 0;
}
题目三:岁月留痕
这题并没有多少心机,记住用一个数组即可模拟所有的月份天数连续情况。
#include<iostream>
using namespace std;
typedef unsigned int ui;
ui m[48] = { 31,28,31,30,31,30,31,31,30,31,30,31,31,29,31,30,31,30,31,31,30,31,30,31,31,28,31,30,31,30,31,31,30,31,30,31,31,28,31,30,31,30,31,31,30,31,30,31 };//一个数组便将所有情况模拟
int main() { //切记,闰年在数组中,一定出现一次
ui n;
cin >> n;
ui* t = new ui[n];
for (ui i = 0; i < n; i++)cin >> t[i]; //输入的月份序列
bool jd = 0;
ui cnt = 0;
for (ui j = 0; j <48; j++) {
if (t[0] == m[j]) { //数据不是很大,可以用蛮力枚举查找
ui i = 0; //第一项匹配,即可开始判定
for (ui k = j; i < n; k++) { //依次匹配完
if (t[i] == m[k])
{
if (t[i] == 29)cnt++;
jd = 1;
i++;
}
else {
jd = 0; break;
}
}
}
if (jd) break; //如果经历一串判定,jd保留为真,则可跳出(已找到)
}
if (jd)cout << "Yes";
else cout << "No";
delete[]t;
return 0;
}
题目四:排队喝水
#include<iostream>
using namespace std;
typedef unsigned int ui;
struct student{ //定义学生结构体,注:二维数组也能满足要求,前提是,记住行列表达的属性
ui qt; //结构体比多维数组清晰了许多,结构体的每个属性,代表多维数组的一维
ui mt; //本题的两维:qt,开始时间;mt,最大的容忍时间
};
int main() {
ui T;
cin >> T; //有T个测试案例,则可用下面的模板,每次循环,对一个案例作解
while(T--){
ui n;
cin >> n;
ui* res = new ui[n]; //n个结果
student* t = new student[n]; //n个学生,创建student动态数组
for (ui i = 0; i < n; i++) {
cin >> t[i].qt >> t[i].mt; //输入每个学生的成员(亦可类似地看作二维数组的各维)
}
ui k = 1; //标记开始的时间
for (ui i = 0; i < n; i++) { //依次对每个学生进行解答
while(k < t[i].qt)k++; //模拟时间的推移
if (k > t[i].mt) { res[i] = 0; } //判断
else { res[i] = k; k++; } //用res储存结果
}
for (ui i = 0; i < n; i++)cout << res[i] << ' '; //依次输出
delete[]t;
delete[]res;
cout<<endl; //进入下一次循环,换行
}
return 0;
}
模拟好时间的推移即可。(用二维数组要注意理清行列的意义)0_0
第五题:阿迪看医生
依旧是数组的强模拟
#include<iostream>
using namespace std;
typedef unsigned int ui;
int main() {
ui n;
cin >> n; //n个医生
ui* a = new ui[n]; //a,b数组模拟医生的能看病的日期
ui* b = new ui[n];
for (ui i = 0; i < n; i++) {
cin >> a[i] >> b[i];
}
ui k = 0; //re从零开始的答案输出
for (ui i = 0; i < n; i++) { //从第一个医生开始看起
if (i == 0) k+= a[0]; //面对第一个,直接天数跳到他开始看病的那天
else {
if (k <a[i])k = a[i]; //如果目前的天数较小,跳转到开始看病的那天
else {
ui tmp = a[i]; //否则依次判断,每次加个天数间隔b[i],直到恰好大于k
while (tmp <=k) tmp += b[i];
k = tmp;
}
}
}
cout << k << endl;
delete[]a;
delete[]b;
return 0;
}
第六题:松雅的花园(重点)
直接上代码暴力模拟
//暴力的模拟方法
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
typedef int ui;
int main() {
ui T;
cin >> T;
while (T--) {
ui n, k;
cin >> n >> k;
ui* w = new ui[k]; //water w[]代表浇头
for (ui i = 0; i < k; i++)cin >> w[i];
bool* hua = new bool[n + 1](); //bool hua 模拟有无浇水
ui j = 1;
while (1) {
for (ui i = 0; i < k; i++) {
ui mi = max(w[i] - (j - 1), 1); //include<cmath>
ui mx = min(w[i] + (j - 1), n); //表示能浇到水的花花范围
for (ui L = mi; L <= mx; L++) { //模拟花浇到水之后的状态
hua[L] = 1;
}
}
if (count(hua, hua + n + 1, 1) == n) { cout << j << endl; break; }
j++; //STL,(还没学的同学直接用就对了,同sort类比
} //count(查找的首地址,查找的尾地址,所查找的元素),返回所查找元素的个数
delete[]hua;
delete[]w;
}
return 0;
}
题目七:拜送朋友
这也是一道简单的题目,但要审清题意,线路安置的范围在哪(可为负数)
#include<iostream>
#include<algorithm>
using namespace std;
struct road {
int mi;
int mx; //定义road结构体,表开始的站点和末站点(一样,二维数组使用时,要理清关系)
};
bool cmp(road r1, road r2) {
return r1.mi < r2.mi; //众所周知,sort默认就不认得,复合类型,所以要用函数规定规则
}
int main(){
int n,y;
cin >> n >> y;
road* t = new road[n];
for (int i = 0; i < n; i++) {
cin >> t[i].mi >> t[i].mx;
}
sort(t, t + n, cmp); //将路段按出发点从小到大排序
for (int i = 1; i < n; i++) { //将第一个路段拓展,看最终能不能包括【0,Y】段
if (t[i].mi <= t[0].mx && t[i].mx > t[0].mx)t[0].mx = t[i].mx;
if (t[i].mi < t[0].mi && t[i].mx >= t[0].mi)t[0].mi = t[i].mi;
}
if (t[0].mx >= y&&t[0].mi<=0)cout << "Yes";
else cout << "No";
delete[]t;
return 0;
}
题目八:猴导师(重点)
本题的难点在冲突猴子的排除
用二维数组,或结构体,记录冲突情况 ,并加以判定
#include<iostream>
using namespace std;
struct d {
int x;
int y;
};
int main() {
int n, k;
cin >> n >> k;
int* a = new int[n];
for (int i = 0; i < n; i++)cin >> a[i]; //n只猴子
d* b = new d[k];
for (int i = 0; i < k; i++)cin >> b[i].x >> b[i].y; //冲突对
for (int i = 0; i < n; i++) {
int sum = 0, m = 0;
for (int j = 0; j < n; j++) {
if (j != i && a[i] > a[j]) {
sum++;
for (int t = 0; t < k; t++) {
if (b[t].x == i + 1) { m = b[t].y;}
else if (b[t].y == i + 1) { m = b[t].x;}
if (j == m - 1) { sum--; } //关键的判定所在,有冲突猴子对应,sum--
}
}
}
cout << sum << ' ';
}
delete[]a;
return 0;
}
题目九:贪心的阿迪(重点)
幸好没出现极大的测试数据,一波蛮力枚举即可
https://blog.csdn.net/woaitangru/article/details/110196447?ops_request_misc=%257B%2522reques
#include<iostream>
#include<algorithm>
using namespace std;
int main() {
int n, k, M, D, i;
cin >> n >> k >> M >> D;
int a[M]; //储存每次循环阿迪所有的糖果
for (i = 0; i < M; i++) {
a[i] = 0;
}
int D1, n1;
D1 = D;
n1 = n;
for (i = 1; i <= M; i++) { //一开始分配一个糖果
D = D1;
n = n1;
for (int j = 0;; j++) { //糖果的分配 给安迪逐次分配糖果
if (D <= 0) {
break; //如果分配数超了,就break
}
n -= i * k; //每分配一次,糖果就相应的减少
a[i - 1] += i; // 给安迪分配糖果 然后存在数组中
if (n < i) {
break;//如果剩余糖果小于应分配数糖果,跳出循环
}
D--;
if (n <= 0) { //没糖果就break
break;
}
}
}
sort(a, a + M); //用sort升序排序,STL,暴力枚举可以用set容器(可自动排序,去重)
cout << a[M - 1]; // 然后输出最大的
return 0;
}
题目十:飞机起飞时间安排(重点)可以说是比较难的模拟题了
#include<iostream>
using namespace std;
int main()
{
int n, s;
cin >> n >> s;
int fj[n][2];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 2; j++)
{
cin >> fj[i][j];
}
}
int b[n + 1][2];//声明第一维的长度为n+1的原因是需考虑当天的前一天晚上最后一班飞机的着陆时间
for (int i = 0; i < n + 1; i++)
{
for (int j = 0; j < 2; j++)
{
if (i == 0) { b[i][j] = fj[n - 1][j]; }
else { b[i][j] = fj[i - 1][j]; }//向二维数组b存进每天最后一班飞机的着陆的时间
}
}
int x = 0, y = 0, c = 0, total = 0, h = 0, m = 0;
for (int i = 0; i < n + 1; i++)//综合比较
{
if (i < n)
{
x = b[i][0] * 60 + b[i][1];
total = x + 1 + s;//+1为起飞需用时1分钟
if (total >= 24 * 60) { total = total - 24 * 60; }
y = b[i + 1][0] * 60 + b[i + 1][1];//对应航班着陆的时间
c = y - total;
if (c >= (s + 1))
{
h = (total) / 60;
m = total - h * 60;
break;
}
}
else if (i == n)
{
x = b[i][0] * 60 + b[i][1];
total = x + 1 + s;
if (total >= 24 * 60) { total = total - 24 * 60; }
h = (total) / 60;
m = total - h * 60;
}
}
cout << h << ' ' << m << endl;
return 0;
}
飞机起飞时间安排(C++练习题)_LG.田猿的博客-CSDN博客
(引用这位前辈的题解,我自己写的更加复杂)
其中的关系《运算需要好好地理清
第十一题:松雅的旅馆
这里便是柳暗花明
#include<iostream>
#include<cmath> //数组枚举和数学问题罢了
using namespace std;
int main(){
int n,d;
cin >> n>>d;
int* t = new int[n];
for (int i = 0; i < n; i++)cin >> t[i];
int res = 2;
for (int i = t[0] + 1; i < t[n - 1]; i++) {
int mi=10000001;
for (int j = 0; j < n; j++) {
int tmp = abs(t[j] - i);
if (tmp < mi)mi = tmp;
}
if (mi == d)res++;
}
cout << res;
delete[]t;
return 0;
}
第十二题:
#include<iostream>
#include<algorithm> //so easy
using namespace std;
int main(){
int n;
cin >> n;
int* t = new int[n];
for (int i = 0; i < n; i++)cin >> t[i];
int k = count(t, t + n, 1);
cout << k << endl;
for (int j = 1; j < n; j++) {
if (t[j] - t[j - 1] != 1) cout << t[j - 1]<<' ';
if (j == n - 1)cout << t[j];
}
delete[]t;
return 0;
}
第十三题:小希与火车
#include<iostream>
using namespace std; //思路雷同的模拟,不要慌
typedef unsigned long long int ui;
int main(){
ui t;
cin >> t;
while (t--) {
ui L, v, l, r;
cin >> L >> v >> l >> r;
ui sum = 0;
for (ui pos = 1; pos <=L; pos++) {
if (pos % v == 0 && (pos<l || pos>r)) sum++;
}
cout << sum << endl;
}
return 0;
}
第十四题:基于神经网络的垃圾邮箱分类(重点)
#include<iostream>
using namespace std;
int main()
{
int T,N,minX,maxX; //定义
cin>>T;
for(int i=0;i<T;i++)
{
int c[2]={0,0}; //定义数组c存储偶数和奇数的个数
cin>>N>>minX>>maxX;
int b[N][2]; //定义数组b存储各层的wi和bi
for(int x=0;x<N;x++) //输入各层wi和bi
{
for(int y=0;y<2;y++)
{
cin>>b[x][y];
}
}
int t=minX,s=1;
//定义t存储第一个数据运行的结果,s存储最初数据加一时最终数据的增加值
for(int x=0;x<N;x++) //进行t与s的运算赋值
{
t=t*b[x][0]+b[x][1];
s=s*b[x][0];
} //&,按位与,shu&1,数为奇数则结果为1,否则为一
if(!t&1) c[0]++; //先判断第一个数据的最终结果为奇还是偶
else c[1]++;
for(int i=minX+1;i<=maxX;i++) //随后数据加一结果差值恒为s
{
t=t+s; //故每次循环加s,且t不用归零
if(!t&1) c[0]++; //判断奇偶,记录个数
else c[1]++;
}
cout<<c[0]<<' '<<c[1]<<endl; //输出
}
}
(基于神经网络的垃圾邮件分类_squidsss的博客-CSDN博客
(引用前辈的题解)(我用将大数抽离讨论(按后两位的奇偶特点,判断),小数常规输出,分支较多。
(注:本题解起参考价值)