1.Jelly (三维走迷宫)
https://ac.nowcoder.com/acm/contest/23156/1004
题目描述
Nancy喜欢吃果冻!
Nancy钻进了一个n×n×nn \times n \times nn×n×n的果冻里,她想从(1,1,1)一路上、下、左、右、前、后六个方向吃到(n,n,n)。
但果冻毕竟是有许多口味的,标记为*的口味是Nancy不愿意吃的,其余的果冻均标记为.。
Nancy不想吃坏肚子,于是她想尽可能少的吃果冻。
下面给出果冻的情况,请你帮忙计算一下她能吃多少块果冻叭!
输入描述:
第一行:一个整数n。 接下来n层,每组n行,每行n列,表示果冻(i,j,k)的情况(如题目描述所述)。 数据满足:1≤n≤1001 \leq n \leq 1001≤n≤100,保证果冻(1,1,1)不是Nancy不愿意吃的。
输出描述:
如果可以到达(n,n,n),请输出路上吃的果冻数量,否则请输出-1。
输入
2 .* .. *. ..
输出
4
吃果冻,求最短步数,想到bfs,只不过是三维的bfs,模板题直接套
复习下bfs原理:通过队列来储存数据,每一次取出队首元素,将其周围符合条件的数据放入队尾,每一次优先处理的是队首即上一层的数据,从而实现按层遍历,适合求最短路径
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
char a[105][105][105];
bool visit[105][105][105]; //判断是否走过
int n;
int d[6][3]={0,0,1,0,0,-1,0,1,0,0,-1,0,1,0,0,-1,0,0}; //标记下一步
struct node{
int x,y,z,step; //结构体存储坐标和步数
};
queue<node>q;
bool flag;
void bfs(){
q.push({1,1,1,1});
visit[1][1][1]=1;
while(!q.empty()){
node p=q.front(); //先取出队首元素,进行判断
q.pop(); //出队
for(int i=0;i<6;i++){
int dx=p.x+d[i][0],dy=p.y+d[i][1],dz=p.z+d[i][2];
if(dx<1||dy<1||dz<1||dx>n||dy>n||dz>n||visit[dx][dy][dz]==1)continue;
if(a[dx][dy][dz]=='*')continue; //坏的不吃
if(dx==n&&dy==n&&dz==n){ //下一步走到(n,n,n),输出步数
cout<<p.step+1;
flag=1;
return;
}
visit[dx][dy][dz]=1; //标记
q.push({dx,dy,dz,p.step+1});
}
}
return;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
for(int k=1;k<=n;k++){
cin>>a[i][j][k];
}
}
}
bfs();
if(!flag)cout<<-1;
return 0;
}
2.幸运数字
https://ac.nowcoder.com/acm/contest/23156/1011
题目描述
定义一个数字为幸运数字当且仅当它的所有数位都是4或者7。
比如说,47、744、4都是幸运数字而5、17、467都不是。
定义next(x)为大于等于x的第一个幸运数字。给定l,r,请求出next(l) + next(l + 1) + ... + next(r - 1) + next(r)。
输入描述:
两个整数l和r (1 <= l <= r <= 1000,000,000)。
输出描述:
一个数字表示答案。
输入
2 7
输出
33
输入
7 7
输出
7
利用bfs打表,dfs也行,但是bfs打出的表天然有序,dfs需要排序
思路:先将0-1000000000内的幸运数字打表
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[3010],cnt=0;
void bfs(){
queue<ll>q; //队列储存节点
q.push(0);
while(!q.empty()){
ll t=q.front();
q.pop();
q.push(t*10+4);
a[cnt++]=t*10+4;
q.push(t*10+7);
a[cnt++]=t*10+7;
if(cnt==3000)break; //打3000个数
}
return;
}
int main(){
bfs(); //打表
ll l,r;
cin>>l>>r;
ll ans=0;
for(ll i=l;i<=r;i++){
ll t=lower_bound(a,a+cnt,i)-a; //搜索大于等于当前数的第一个数
ans+=a[t]*(min(a[t],r)-i+1);
i=a[t]; //更新左端点
}
cout<<ans;
return 0;
}