这些题目都是在牛客网上搜集的,也参考了一些大佬的代码。
对题目进行了详细的描述,并提供了输入输出示例,参考代码也更适合基础薄弱的参看。
希望大家可以一起交流学习,offer拿到手软!!!
/* 华为的机试题0707-1: 贪心做法 题目: 有n个事件,每个事件形式为(t,w),表示若在t时刻前完成该事件,获得w分数,每一个小时只能完成一个事件,求最大能获得的分数 事件数量<=1000000 输入: 7 1 6 1 7 3 2 3 1 2 8 2 10 6 1 输出:21 */ #include<bits/stdc++.h> using namespace std; int main() { auto cmp = [](const vector<int> &a, const vector<int> &b) { // if(a[0] == b[0]) return a[1]>b[1]; // else return a[0]<b[0]; return a[0]<b[0]; }; int N; cin>>N; vector<vector<int>> nums; vector<int> v_temp; int a, b; for(int i=0; i<N; i++) { cin>>a>>b; v_temp.push_back(a); v_temp.push_back(b); nums.push_back(v_temp); v_temp.clear(); } sort(nums.begin(), nums.end(), cmp); //按时刻进行排序,对于时刻相同的,分值大的优先(实际这个没必要,因为接下来会用小顶堆替换掉以前时刻分值小的) for(int i=0; i<nums.size();i++) { cout<<nums[i][0]<<':'<<nums[i][1]<<endl; } priority_queue<int,vector<int>, greater<int>> pq; //就是为了解决出现时刻相同的情况,如果分值大,则会替换以前时刻的工作 pq.push(nums[0][1]); for(int i=1; i<nums.size(); i++) { cout<<"Top is"<<pq.top()<<endl; if(nums[i][0] == nums[i-1][0]) //出现了时刻相等,就要判断相等时刻的分值是否比以前的大,如果是则直接替换掉 { if(nums[i][1] > pq.top()) { cout<<"Delete " <<pq.top()<<endl; pq.pop(); pq.push(nums[i][1]); } } else //对于不同时刻直接压入小顶堆就可以了 { pq.push(nums[i][1]); } } int result = 0; while(!pq.empty()) { result += pq.top(); pq.pop(); } cout<<result<<endl; return 0; }
/* 华为的机试题0707-2: 图搜素 给定一个有向图以及一个起点,问是否只从起点出发就可以走到全部的点,如果可以,输出起点到其他点的最长距离 点数<=100, 边数<=5000,路径的长度小于100 输入: [1,2,15] [1,3,14] [3,4,9] 4 1 输出:23; 路线1-3-4.虽然不经过2,但是1可以到2,所以算能到达。 输入如上,前三行分别代表景点1到景点2之间有路,距离为15,景点1到景点3之间有路,距离为14,景点3到景点4之间有路,距离为9。 接下来输入一共有多少个景点,下一行是起始景点。问是否能逛完,可以的话求最长路径,否则输出-1.景点数小于100,路径长度小于100,两个景点间路径数小于5000. */ #include<bits/stdc++.h> using namespace std; vector<vector<int>> graph(100, vector<int>(100, 0)); vector<bool> visited(100, false); int max_path = 0; void dfs(int start, int N, int path) { visited[start] = true; for(int i=0; i<N; i++) { if(graph[start][i]>0 && !visited[i]) { path += graph[start][i]; //这才是在深度方向上相加 dfs(i, N, path); max_path = max(path, max_path); path -= graph[start][i]; } } } int main() { string s; int start; int N; while(getline(cin, s)) { // cout<<"s="<<s<<endl; if(s[0] == '[') { s = s.substr(1, s.size()-2); int i, j, val; int pos = s.find(','); i = stoi(s.substr(0, pos)); s = s.substr(pos+1); pos = s.find(','); j = stoi(s.substr(0, pos)); s = s.substr(pos+1); val = stoi(s); // cout<<"i="<<i<<";j="<<j<<";val="<<val<<endl; graph[i-1][j-1] = val; } else { N = stoi(s); cin>>s; start = stoi(s)-1; // cout<<"N="<<N<<";start="<<start<<endl; break; } } dfs(start, N, 0); for(int i=0; i<N; i++) { if(!visited[i]) { cout<<-1<<endl; return 0; } } cout<<max_path<<endl; return 0; }
/* 华为的机试题0707-3: dfs暴搜就可以 题目: 题目大意:在中国象棋中,给出大小为m*n的棋盘,棋盘上有一些障碍点,以及一匹马在S处要到T点, 给出中国象棋中跳马的规则,问至少需要多少步才能跳到T点 数据范围m, n< = 150 输入: 对于输入的解释,4是行,5是列,#是障碍物,H是起始点,T是终止点 4 5 ***#* *H*** **T#* #**** 输出:从H到T最小的步数 4 */ #include<bits/stdc++.h> using namespace std; int min_val = INT_MAX; vector<int> directions_x = {2, 2, -2, -2, 1, 1, -1, -1}; vector<int> directions_y = {1, -1, 1, -1, 2, -2, 2, -2}; void dfs(vector<vector<char>> &graph, vector<vector<bool>> &visited, int i, int j, pair<int, int> end, int step) { if(i<0 || i>=graph.size() || j<0 || j>=graph[0].size() || visited[i][j] || graph[i][j] == '#') { return; } if(i == end.first && j == end.second) { min_val = min(step, min_val); return; } visited[i][j] = true; step++; for(int k=0; k<8; k++) { int x = i+directions_x[k]; int y = j+directions_y[k]; dfs(graph, visited, x, y, end, step); } visited[i][j] = false; step--; } int main() { int m, n; cin>>m>>n; vector<vector<char>> graph(m, vector<char>(n, '*')); vector<vector<bool>> visited(m, vector<bool>(n, false)); char temp; pair<int, int> start; pair<int, int> end; for(int i=0; i<m; i++) { for(int j=0; j<n; j++) { cin>>temp; graph[i][j] = temp; if(temp == 'H') { start.first = i; start.second = j; } if(temp == 'T') { end.first = i; end.second = j; } } } dfs(graph, visited, start.first, start.second, end, 0); if(min_val == INT_MIN) { cout<<-1<<endl; } else { cout<<min_val<<endl; } return 0; }
全部评论
(3) 回帖