写在前面:本题解旨在帮助进行作业参考,为学习升华所用。登高自卑,戒骄戒躁。
第一题:快速公交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+1cnt += (L - jt[n - 1]) / a; //同理,如果L-最晚的结束时间,cnt+1for (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],直到恰好大于kwhile (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) { //没糖果就breakbreak;}}}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和bifor(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博客
(引用前辈的题解)(我用将大数抽离讨论(按后两位的奇偶特点,判断),小数常规输出,分支较多。
(注:本题解起参考价值)