版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014744127/article/details/79431847 </div><link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-f57960eb32.css"><div id="content_views" class="markdown_views prism-atom-one-dark"><!-- flowchart 箭头图标 勿删 --><svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path></svg><p>先挖坑,昨天刚刚帮师兄做的题目。过两天有时间来填坑。<br>
算法岗是地图上色,相邻块颜色不同问题,类似以前奥数的五色地图。递推求公式可解。
###/填坑部分*****/
###题目表述:
一个圆分成n个扇形,用m种颜色上色,要求相邻两个颜色不同。求有多少种不同的方法。
###思路:
首先考虑一些奇怪的临界值
n=1:有m种可能。
n=2:有m(m-1)种可能。
m<2:并且n>2:毫无可能。
然后考虑正常情况
第一个扇面有m种可能,在不考虑最后一个和第一个扇面的颜色关系情况下,后面的n-1块都是有m-1种可能性。但这样得到的可能性是多的,接下来就是要考虑减去第一块和最后一块同色的情况。
当同色时候,其实可以把两个扇面融合,看成一个扇面,这是本题求解的关键。这样减去的部分就可以变成问题参数是(n-1,m)时得到的可能性。
递归表达式出来了:
###S(n,m) = m*(m-1)^(n-1) - S(n-1,m)
其实可以进一步运用高中数学中数列知识,把m看成常数,配一下项,变成等比数列,直接得到最后通式:
###Sn = (-1)^n * (m-1) + (m-1)^n
具体操作不展开了…因为我懒,并且打公式好烦。
代码如下:
#include <iostream>
#include <math.h>
using namespace std;
double digui(int n, int m){if(n==1)return m;if(n==2){if (m<2)return 0.0;return (double)m*(m-1);}return m*pow(double(m-1), double(n-1))-digui(n-1, m);
}
int main(){int N, M;cin >> N >> M;int ans = 0;ans=(int)digui(N,M);printf("%d", ans);return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
开发岗是求矩阵最短路径,DP思想,构建状态矩阵可解。
###/填坑部分*****/
###题目表述:
一行方格还是瓷砖n个,有m种颜色可以用来上色,每个格子上色的价格是不同(比如第一个上红色5元,第二个上红色3元)。要求相邻格子的颜色不同情况下,最小花费是多少。
输入格式:
n m
第一格填不同颜色的价格:a b c …(一共m行)
。
。
。
第n格…
比如:
3 3
12 10 8(给第一个格子上色,三种颜色的价格)
6 5 4
9 5 4
###思路:
第一眼以为和算法岗一样,后来仔细一看就发现天差地别。这是经典的DP,状态转移。
找不到题目了,拍照不清楚。。。
大概就是一个矩阵,里面都是正数,然后从最上面走到最下面最小cost是多少这种题目一样,只不过加了一个不能相邻格子走直线而已。
</div><link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-258a4616f7.css" rel="stylesheet"></div>
先挂题目
————————————————————————————————————————————————————————
光明小学的小朋友们要举行一年一度的接力跑大赛了,但是小朋友们却遇到了一个难题:设计接力跑大赛的线路,你能帮助他们完成这项工作么?
光明小学可以抽象成一张有N个节点的图,每两点间都有一条道路相连。光明小学的每个班都有M个学生,所以你要为他们设计出一条恰好经过M条边的路径。
光明小学的小朋友们希望全盘考虑所有的因素,所以你需要把任意两点间经过M条边的最短路径的距离输出出来以供参考。
你需要设计这样一个函数:
res[][] Solve( N, M, map[][]);
注意:map必然是N * N的二维数组,且map[i][j] == map[j][i],map[i][i] == 0,-1e8 <= map[i][j] <= 1e8。(道路全部是无向边,无自环)2 <= N <= 100, 2 <= M <= 1e6。要求时间复杂度控制在O(N^3*log(M))。
map数组表示了一张稠密图,其中任意两个不同节点i,j间都有一条边,边的长度为map[i][j]。N表示其中的节点数。
你要返回的数组也必然是一个N * N的二维数组,表示从i出发走到j,经过M条边的最短路径
你的路径中应考虑包含重复边的情况。
——————————————————————————————————————————————————————
题目特别长,加上有点紧张,光是读题目就花了很久的时间。泪流满面谨以此题纪念即将三挂阿里的我。
——————————————————————————————————————————————————————
思路有点类似与求和问题,牛客网上的一道题目https://www.nowcoder.com/practice/11cc498832db489786f8a03c3b67d02c?tpId=85&&tqId=29869&rp=1&ru=/activity/oj&qru=/ta/2017test/question-ranking但不完全一样。有兴趣可以做做。
先挂代码吧。。。
- package ali;
-
- import java.util.Scanner;
-
- public class zhaolu {
- public static void main(String[] args) {
- Scanner input = new Scanner(System.in);
- int n = input.nextInt();
- int m = input.nextInt();
- long[][] map = new long[n][n];
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < n; j++) {
- map[i][j] = input.nextLong();
- }
- }
- long[][] res = new long[n][n];
- for (int i = 0; i < res.length; i++) {
- for (int j = 0; j < res.length; j++) {
- res[i][j] = Integer.MAX_VALUE;
- }
- }
- for (int i = 0; i < n; i++) {
- int nowrow = i;
- int nowcol = i;
- int distance = 0;
- solve(nowcol, m, map, res, distance, nowrow);
- }
- for (int i = 0; i < res.length; i++) {
- for (int j = 0; j < res.length; j++) {
- System.out.print(res[i][j] + " ");
- }
- System.out.println();
- }
-
- }
-
- public static void solve(int nowcol, int m, long[][] map, long[][] res, long distance, int nowrow) {
- if (m == 0) {
- if (distance < res[nowrow][nowcol]) {
- res[nowrow][nowcol] = distance;
- return;
- }
- return;
- }
- for (int nextcol = 0; nextcol < map[0].length; nextcol++) {
- if (nowcol != nextcol) {
- solve(nextcol, m - 1, map, res, distance + map[nowcol][nextcol], nowrow);
- }
- }
- return;
- }
-
- }
其实就一个solve函数。
nowrow,记录当前是哪一个出发点,每一行可以对应一个出发点。
nowcol,记录当前走到了哪一个节点。
m,用来记录还需要走多少步。
res,记录最短路径的矩阵
distance,表示当前走的距离
跳出递归的条件是,m==0也就是走完了规定的步数,更改记录的条件是,当前这种走法比以前的走法都要短。
递归过程中下一步是不能与当前位置重合的。
突然发现没什么好讲的了……这题思路并不难,就是参数比较多,处理起来容易出错……
祝大家好运~我再去哭一会儿……
编程题共3道,貌似与其它岗位的小伙伴题目都不一样,本人遇到的难度较低。另外题面包含错别字以及描述不太清晰,值得吐槽。
第一题 最小整数
有一个32位整数n,试找一个最小整数m,使得m的每一位之积等于n,如果找不到这样的整数,输出0
分析可知,整数m的所有位均为2-9的整数,对n做质因数分解变形(每次从9-2取数字做整除),能成功分解证明可以找到合适的整数,然后对分解出来的数字进行排序,从小到大输出,未发现明显trick,1A
- #include <iostream>
- #include <cstdio>
- #include <cmath>
- #include <cstring>
- #include <cstdlib>
- #include <algorithm>
- #define LL long long
- using namespace std;
- LL m ,n;
- LL item[1000];
- LL cnt;
- int yinshufenjie(LL num){
- cnt =0;
- LL i;
- LL temp = num;
- do{
- temp=num;
- for (i = 9;i >=2 ;i--)
- {
- while (num != i)
- {
- if (num%i == 0)
- {
- item[cnt++] = i;
- num = num / i;
- }
- else break;
- }
-
- }
- }while(temp != num);
-
- if(num<10){
- item[cnt++]=num;
- return 1;
- }
- else{
- return 0;
- }
- }
- int main()
- {
- LL m ,n;
- cin>>n;
- if(yinshufenjie(n)){
- sort(item,item+cnt);
- for(int i=0;i<cnt;i++){
- cout<<item[i];
- }
- cout<<endl;
- }
- else{
- cout<<"0"<<endl;
- }
- return 0;
- }
第二题 NTES子串判断
水题,判断是否存在目标顺序的字符
- #include <iostream>
- #include <cstdio>
- #include <cmath>
- #include <cstring>
- #include <cstdlib>
- #define LL long long
- using namespace std;
- int main(){
- int t;
- char s[101];
- char ntes[10]="NTES\0";
- int len = strlen(ntes);
- cin>>t;
- while(t--){
- cin>>s;
- int cnt =0;
- int l = strlen(s);
- for(int i=0;i<l;i++){
- if(s[i]==ntes[cnt]){
- cnt++;
- }
- if(cnt>len){
- break;
- }
- }
- //cout<<cnt<<endl;
- if(cnt == len){
- cout<<"yes"<<endl;
- }
- else{
- cout<<"no"<<endl;
- }
- }
- return 0;
- }
- /*
- 2
- STNETEDTS
- TSENSTE
- */
第三题 树的深度
给出n 和 n行,n代表树有n个节点,接下来的n行,每一行有两个数字,代表该节点的左右子节点是否存在,1为存在,-1为不存在。节点输入的顺序有序,第一组为根节点的左右子节点,求树的最大深度。
分析:已知节点有序,证明同样深度的节点顺序出现,从子节点信息也可以累加下一层有多少个节点,因此只需要遍历输入,统计当前层和下一层有多少节点,累加深度即可
- #include <iostream>
- #include <cstdio>
- #include <cmath>
- #include <cstring>
- #include <cstdlib>
- #define LL long long
- using namespace std;
- struct node{
- int left;
- int right;
- }tree[101];
- int main(){
- int n;
- cin>>n;
- int father[101];
- int left,right;
- int cp=1;
- int nextp=0;
- int dep = 1;
- for(int i=0;i<n;i++){
- cp--;
- cin>>left>>right;
- if(left>0){
- nextp+=1;
- }
- if(right>0){
- nextp+=1;
- }
- if(cp==0){
- cp=nextp;
- if(cp>0){
- dep+=1;
- }
- nextp=0;
- }
- }
- cout<<dep<<endl;
- return 0;
- }