滴滴0918笔试编程题参考解题报告

阶乘末尾0的个数

分析

考虑0是5和2贡献出来的,但是因子2出现的频率高得多,所以统计因子5的个数就好了。给了多种写法。

参考代码

//第一种
#include <iostream>
#include <cstdio>

using namespace std;

int solve(int n){
    int cnt = 0;
    while(n){
        cnt += n / 5;
        n = n / 5;
    }
    return cnt;
}
int main(){
    int n;
    cin >> n;
    cout << solve(n) << endl;
}
//第二种
#include <iostream>
#include <cstdio>

using namespace std;

int solve(int n){
    int cnt = 0;
    for(int i = 5; i <= n; i += 5){
        int res = i;
        while (res % 5 == 0){
            cnt++;
            res /= 5;
        }
    }
    return cnt;
}
int main(){
    int n;
    cin >> n;
    cout << solve(n) << endl;
}
#数据范围比较小,直接用python也是可以的
n = int(raw_input())
ans = 1;
for i in range(1,n+1):
    ans *= i
count = 0
for i in range(len(str(ans))-1,-1,-1):
    if(str(ans)[i] == '0'):
        count += 1
    else:
        break
print count

地下迷宫

分析

根据题设,可以简单证明最短路径一定体力消耗最小的路径。因为横向移动m-1是必须的,而纵向的路径越短,需要的体力就越少。
直接bfs然后记录一下路径即可,dfs应该也是可以的吧。

参考代码

#include <iostream>
#include <cstdio>
#include <queue>

using namespace std;

int _map[15][15];
int vis[15][15];
int m,n,P;
struct node{
    int x,y,v;
}ans[15][15];
bool bfs(){
    queue<node> q;
    node tmp;
    tmp.x = 0,tmp.y = 0,tmp.v = P;
    q.push(tmp);
    while(!q.empty()){
        node tmp = q.front();
        q.pop();
        if(tmp.x == 0 && tmp.y == m - 1 && tmp.v >= 0) return true;
        if(tmp.x + 1 <= n - 1 && _map[tmp.x + 1][tmp.y] && !vis[tmp.x + 1][tmp.y]){
            node temp;
            temp.x = tmp.x + 1;
            temp.y = tmp.y;
            temp.v = tmp.v;
            ans[temp.x][temp.y].x = tmp.x;
            ans[temp.x][temp.y].y = tmp.y;
            vis[temp.x][temp.y] = 1;
            q.push(temp);
        }
        if(tmp.y + 1 <= m - 1 && _map[tmp.x][tmp.y + 1] && !vis[tmp.x][tmp.y + 1]  && tmp.v > 0){
            node temp;
            temp.x = tmp.x;
            temp.y = tmp.y + 1;
            temp.v = tmp.v - 1;
            ans[temp.x][temp.y].x = tmp.x;
            ans[temp.x][temp.y].y = tmp.y;
            vis[temp.x][temp.y] = 1;
            q.push(temp);
        }
        if(tmp.x - 1 >= 0 && _map[tmp.x - 1][tmp.y] && !vis[tmp.x - 1][tmp.y] && tmp.v >= 3){
            node temp;
            temp.x = tmp.x - 1;
            temp.y = tmp.y;
            temp.v = tmp.v - 3;
            ans[temp.x][temp.y].x = tmp.x;
            ans[temp.x][temp.y].y = tmp.y;
            vis[temp.x][temp.y] = 1;
            q.push(temp);
        }
        if(tmp.y - 1 >= 0 && _map[tmp.x][tmp.y - 1] && !vis[tmp.x][tmp.y - 1] && tmp.v > 0){
            node temp;
            temp.x = tmp.x;
            temp.y = tmp.y - 1;
            temp.v = tmp.v - 1;
            ans[temp.x][temp.y].x = tmp.x;
            ans[temp.x][temp.y].y = tmp.y;
            vis[temp.x][temp.y] = 1;
            q.push(temp);
        }
    }
    return false;
}
void pri(int sx,int sy) {
    if( sx == 0 && sy == 0) {
        printf("[0,0]");
        return ;
    }
    pri(ans[sx][sy].x,ans[sx][sy].y);
    printf(",[%d,%d]", sx,sy);
}
int main(){
    cin >> n >> m >> P;
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            cin >> _map[i][j];
        }
    }
    if(bfs()){
        pri(0, m - 1);
        printf("\n");
    }
    else cout << "Can not escape!" << endl;
    return 0;
}
#滴滴##Java工程师##C++工程师##安卓工程师##前端工程师##算法工程师#
全部评论
好牛逼表示直接放弃
点赞 回复 分享
发布于 2016-09-18 17:02
厉害
点赞 回复 分享
发布于 2016-09-18 17:05
迷宫打印路径总出错 - - 
点赞 回复 分享
发布于 2016-09-18 17:07
第一题花了50多分钟,第二题5分钟就搞定!
点赞 回复 分享
发布于 2016-09-18 17:17
你好,请问题目能放到网站上去吗? 看自己能不能AC
点赞 回复 分享
发布于 2016-09-18 17:39
第二题跟你思路差不多 #include <stdio.h> #include <iostream> #include <algorithm> #include <vector> using namespace std; int map[11][11]; int cnt[100][100]; int flag[100][100]; int inf=100; struct point { int x; int y; }; int f(int n,int m,vector<point> &vec) { int x=0,y=0; while (1) { if(y+1<n&&map[x][y+1]==1&&flag[x][y+1]==0) { cnt[x][y+1]=cnt[x][y]+1; y=y+1; point p;p.x=x,p.y=y; vec.push_back(p); flag[x][y]=1; } else if(x-1<n&&map[x-1][y]==1&&flag[x-1][y]==0) { cnt[x-1][y]=cnt[x][y]+3; x=x-1; point p;p.x=x,p.y=y; vec.push_back(p); flag[x][y]=1; } else if(x+1<n&&map[x+1][y]==1&&flag[x+1][y]==0) { cnt[x+1][y]=cnt[x][y]; x=x+1; point p;p.x=x,p.y=y; vec.push_back(p); flag[x][y]=1; } else if(y-1<n&&map[x][y-1]==1&&flag[x][y-1]==0) { cnt[x][y-1]=cnt[x][y]+1; y=y-1; point p;p.x=x,p.y=y; vec.push_back(p); flag[x][y]=1; } else { point p=*(vec.end()-1); map[p.x][p.y]=0; flag[p.x][p.y]=0; vec.pop_back(); } //cout<<x<<","<<y<<endl; if(x==0&&y==m-1) break; } return vec.size(); } int main() { int n,m,p; while (cin>>n>>m>>p) { for(int i=0;i<n;i++) { for(int j=0;j<m;j++) cin>>map[i][j]; } vector<point> vec; int rtn = f(n,m,vec); if(rtn>=p) cout<<"Can not escape!"<<endl; else { cout<<"[0,0]"; for(int i=0;i<vec.size();i++) cout<<",["<<vec[i].x<<","<<vec[i].y<<"]"; cout<<endl; } } }
点赞 回复 分享
发布于 2016-09-18 21:39
第一题动态规划解法,代码没优化,中间还有调试用的输出,额,有点长。大体思想,先求出(0,0)到各个点的最大剩余体力,然后从(0,m)开始倒推路径。 import java.util.Arrays; import java.util.Scanner; import java.util.Stack; public class Main { public static void main(String[] args){ Scanner sc = new Scanner(System.in); while(sc.hasNext()){ int n = sc.nextInt(); int m = sc.nextInt(); int P = sc.nextInt(); int[][] nums = new int[n][m]; for(int i=0; i<n; i++){ for(int j=0; j<m; j++){ nums[i][j] = sc.nextInt(); } } if(n == 1){ System.out.println(P - m + 1); } if(m == 1){ System.out.println(P); } int[][] tili = new int[n][m]; for(int i=0; i<n; i++){ for(int j=0; j<m; j++){ tili[i][j] = -1; } } getSolution(nums, tili, P); dis(nums); System.out.println("tili"); dis(tili); findPath(nums, tili); } } public static void getSolution(int[][] nums, int[][] tili ,int P){ int n = nums.length; int m = nums[0].length; tili[0][0] = P; for(int i=0; i<n; i++){ for(int j=0; j<m; j++){ if(nums[i][j] == 0){ continue; } update(nums, tili, i, j); } } } public static void update(int[][] nums, int[][] tili, int i, int j){ if(tili[i][j] <= 0){ return; } if(i>0){ if(nums[i-1][j] == 1){ int p = tili[i][j] - 3; if(tili[i-1][j] < p){ tili[i-1][j] = p; update(nums, tili, i-1, j); } } } if(i<nums.length-1){ if(nums[i+1][j] == 1){ int p = tili[i][j]; if(tili[i+1][j] < p){ tili[i+1][j] = p; update(nums, tili, i+1, j); } } } if(j > 0){ if(nums[i][j-1] == 1){ int p = tili[i][j] - 1; if(tili[i][j-1] < p){ tili[i][j-1] = p; update(nums, tili, i, j-1); } } } if(j < nums[0].length-1) { if(nums[i][j+1] == 1){ int p = tili[i][j] - 1; if(tili[i][j+1] < p){ tili[i][j+1] = p; update(nums, tili, i, j+1); } } } } public static void findPath(int[][] nums, int[][] tili){ int n = tili.length; int m = tili[0].length; if(tili[0][m-1] == -1){ System.out.println("Can not escape!"); } Stack<String> stack = new Stack<String>(); String str = "[0," + (m-1) + "]"; stack.push(str); findnext(tili, 0, m-1, stack); while(!stack.isEmpty()){ System.out.print(stack.pop()); if(!stack.isEmpty()){ System.out.print(","); } } } public static void findnext(int[][] tili, int i, int j, Stack<String> s){ if(i==0 && j==0){ // String str = "[0,0]"; // s.push(str); return; } int up=0, down=0, left=0, right=0; int cur = tili[i][j]; if(i > 0){ up = tili[i-1][j]; if(up == cur){ String str = "[" + (i-1) + "," + j + "]"; s.push(str); findnext(tili, i-1, j, s); return; } } if(i < tili.length-1){ down = tili[i+1][j]; if(cur == down - 3){ String str = "[" + (i+1) + "," + j + "]"; s.push(str); findnext(tili, i+1, j, s); return; } } if(j >0){ left = tili[i][j-1]; if(cur == left - 1){ String str = "[" + (i) + "," + (j-1) + "]"; s.push(str); findnext(tili, i, j-1, s); return; } } if(j < tili[0].length-1){ right = tili[i][j+1]; if(cur == right - 1){ String str = "[" + (i) + "," + (j+1) + "]"; s.push(str); findnext(tili, i, j+1, s); return; } } } public static void dis(int[][] nums){ for(int i=0; i<nums.length; i++){ System.out.println(Arrays.toString(nums[i])); } } }
点赞 回复 分享
发布于 2016-09-18 21:52
第二道题,你是如何保证得到的路径体力消耗一定是最少的呢?
点赞 回复 分享
发布于 2016-09-21 09:18
我用DFS只过了 90% 
点赞 回复 分享
发布于 2016-09-21 09:24
#include <iostream> #include <vector> #include <climits> using namespace std; vector<vector<int> > map; int maxf = INT_MIN; vector<pair<int,int>> shortesresult; /* To find the path with least cost; Move left or right costs 1 Move Up costs 3 Move down costs 0 input: 4 4 10 // n m p p is total allowed cost 1 1 1 1 1 1 1 1 0 0 0 1 0 0 1 1 */ bool dfs(int x,int y,int n,int m,int p,vector<pair<int,int>> &result){ if(p <= 0){ return false; //  } if(x == 0 and y == m){ result.push_back({x,y}); for(auto &p : result){ //cout << '[' << p.first << "," << p.second << ']'; } //cout << p << endl; if(p > maxf){ shortesresult = result; maxf = p; } result.pop_back(); // bug!!!!!! return true; } if(x < 0 || y < 0 || x > n || y > m ){ return false; } if(map[x][y] <= 0){ return false; } //cout << x << " " << y << " " << p << endl; result.push_back({x,y}); map[x][y] = -1; bool r1 = dfs(x + 1,y,n,m,p,result); bool r2 = dfs(x,y + 1,n,m,p - 1,result); bool r3 = dfs(x,y - 1,n,m,p - 1,result); bool r4 = dfs(x - 1,y,n,m,p -  3,result); result.pop_back(); map[x][y] = 1; return false; } int main(){ int n,m,p,tmp; cin >> n >> m >>p; map = vector<vector<int> >(n,vector<int>(m,0)); for(int i = 0; i < n; i ++){ for(int j = 0;j < m;j ++){ cin >> tmp; map[i][j] = tmp; } } vector<pair<int,int>> result; bool isFirst = true; dfs(0,0,n-1,m-1,p,result); if(shortesresult.size() != 0){ for(auto &p : shortesresult){ if(!isFirst){ cout << ','; } cout << '[' << p.first << "," << p.second << ']'; isFirst = false; } }else{ cout << "Can not escape!" << endl; } cout << endl; }
点赞 回复 分享
发布于 2016-09-21 09:33
大家报的都是神马职位?
点赞 回复 分享
发布于 2016-09-22 04:35

相关推荐

评论
点赞
37
分享
牛客网
牛客企业服务