一、扫地机器人
题目链接:扫地机器人 - 蓝桥云课 (lanqiao.cn)
题目要求:
小明公司的办公区有一条长长的走廊,由 N 个方格区域组成,如下图所示。
走廊内部署了 K 台扫地机器人,其中第 i 台在第 Ai 个方格区域中。已知扫地机器人每分钟可以移动到左右相邻的方格中,并将该区域清扫干净。
请你编写一个程序,计算每台机器人的清扫路线,使得
1.它们最终都返回出发方格,
2.每个方格区域都至少被清扫一遍,
3.从机器人开始行动到最后一台机器人归位花费的时间最少。
注意多台机器人可以同时清扫同一方块区域,它们不会互相影响。
输出最少花费的时间。 在上图所示的例子中,最少花费时间是 6。第一台路线:2-1-2-3-4-3-2,清 扫了 1、2、3、4 号区域。第二台路线 5-6-7-6-5,清扫了 5、6、7。第三台路线 10-9-8-9-10,清扫了 8、9 和 10。
解题思路:
题目要求最少花费时间。由于每个机器人的工作时间可能不同,那么这些机器人各自的花费时间中的最大值(设为 t )的就是本题要求的答案,我们需要做的是使得 t 最小。将最大花费时间(t)最小化,显然我们需要使用二分求解。
我们假设某个机器人需要清扫 a,b,c,d 四个格子,因为这个机器人清扫完还需要回到最初始的位置,所以无论这个机器人初始位置在什么地方,其清扫路径的本质都是重复两次 a 到 b,b 到 c,c 到 d 的过程,花费时间为 6,由此,我们假设某个机器人清扫的格子范围为 l, 那么这个机器人花费的时间为 2(l−1)×2。所以我们只需要对机器人清扫的范围(l)进行二分即可,最后的答案为t=(l−1)×2。
显然当每个机器人清扫的范围大小相同时,花费时间最小。我们可以对清扫范围进行二分,然后验证其答案的正确性即可,判断条件是清扫范围可以使得每个格子都能够扫到
我们可以明显的知道,最左边的格子由左边第一台机器人清扫,花费时间是最少的,在此我们可以采用贪心的思想,我们让每台机器人都要优先清扫其左边还未扫的到格子,然后再往右扫,在二分得到的范围下往右扫得越多越好,这样可以减少右边下一个机器人需要往左扫的范围,增加其往右扫的范围,以此类推,可减少清扫时间。
二分加贪心,主要是check函数的使用,二分的点就难在这里和边界,大家一定要理解!吃透它。
#include<bits/stdc++.h> using namespace std; int a[100001]; int n,k; bool check(int x) { int sum = 0; for(int i=1;i<=k;i++) { if(a[i]-x<=sum) { if(a[i]<=sum) { sum = a[i] + x - 1; } else { sum += x; } } else { return 0; } } return sum>=n; } int main() { cin>>n>>k; for(int i=1;i<=k;i++) { cin>>a[i]; } sort(a+1,a+1+k); int l = 0,r = n,m,num; while(l<=r) { m = l+r>>1; if(check(m)) { r = m - 1; num = m; } else { l = m + 1; } } cout<<(num-1)*2; return 0; }
二、全球变暖
题目链接:全球变暖 - 蓝桥云课 (lanqiao.cn)
题目要求:
你有一张某海域 NxN 像素的照片,"."表示海洋、"#"表示陆地,如下所示:
.......
.##....
.##....
....##.
..####.
...###.
.......
其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有 2 座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:
.......
.......
.......
.......
....#..
.......
.......
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
解题思路:
定义两个数组 一个地图一个标记 如果没有搜过并且为#就dfs下去,然后每次都判断一下是否为四处都是陆地 如果是的话标记一下 通过标记判断有几个被淹没了。
xx和yy是方向
#include<bits/stdc++.h> using namespace std; const int N = 1010; char mp[N][N]; int vis[N][N]; int xx[] = {0,1,-1,0}; int yy[] = {1,0,0,-1}; int flag; void dfs(int x, int y) { vis[x][y] = 1; if(mp[x][y+1]=='#'&&mp[x][y-1]=='#'&&mp[x+1][y]=='#'&&mp[x-1][y]=='#') { flag = 1; } for(int i=0;i<4;i++) { if(vis[x+xx[i]][y+yy[i]]==0&&mp[x+xx[i]][y+yy[i]]=='#') { dfs(x+xx[i],y+yy[i]); } } } int main() { int n; cin>>n; for(int i=0;i { cin>>mp[i]; } int ans = 0; for(int i=0;i { for(int j=0;j { if(mp[i][j]=='#'&&vis[i][j]==0) { flag = 0; dfs(i,j); if(flag==0) { ans++; } } } } cout<<ans; return 0; }
三、机器人行走
题目链接:机器人行走 - 蓝桥云课 (lanqiao.cn)
题目要求:
某少年宫引进了一批机器人小车。可以接受预先输入的指令,按指令行动。小车的基本动作很简单,只有 3 种:左转(记为 L),右转(记为 R),向前走若干厘米(直接记数字)。
例如,我们可以对小车输入如下的指令:
15L10R5LRR10R20
则,小车先直行 15 厘米,左转,再走 10 厘米,再右转
不难看出,对于此指令串,小车又回到了出发地。
你的任务是:编写程序,由用户输入指令,程序输出每条指令执行后小车位置与指令执行前小车位置的直线距离。
解题思路:
一个大模拟题,按照题意模拟即可,这种模拟一般都是要细心,大家按住性子慢慢来呀。
#include<bits/stdc++.h> using namespace std; int main() { int n; cin>>n; while(n--) { string s; cin>>s; double x=0,y=0; int t=0; for(int i=0;i { if(s[i]=='R') { t++; t %= 4; } else if(s[i]=='L') { t+=3; t%=4; } else { int j=i+1; int sum=s[i]-'0'; while(s[j]!='R'&&s[j]!='L'&&s[j]!='\0') { sum*=10; sum+=s[j]-'0'; j++; } switch(t) { case 1:x+=sum;break; case 2:y+=sum;break; case 3:x-=sum;break; case 0:y-=sum;break; } i=j-1; } } printf("%.2lf\n",sqrt((x-0)*(x-0)+(y-0)*(y-0))); } return 0; }
四、数的幂次
题目链接:数的幂次 - 蓝桥云课 (lanqiao.cn)
题目要求:给定三个正整数 N,M,P,求 NMmodp。
解题思路:
这道题就是快速幂的模板,大家要好好记住,以后遇到这种问题直接套模板即可。
看不懂模板的可以去搜一下快速幂的文章哦。
#include<bits/stdc++.h> #define ll long long using namespace std; ll ksm(ll x,ll n,ll mod) { ll res = 1; while(n) { if(n&1) { res = res * x % mod; } x = x * x % mod; n >>= 1; } return res; } int main() { int t = 1; cin>>t; while(t--) { ll n,m,p; cin>>n>>m>>p; cout<<ksm(n,m,p)<<endl; } return 0; }
今天的题目对于没有学过或者练习过这些知识的小伙伴来说有些挑战,大家好好吃透,会对自己以后的竞赛之路有帮助的~