ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

西安葡萄城校招一面面试题(挺有意思)

2021-09-27 18:30:34  阅读:302  来源: 互联网

标签:std worldCoordinate 面试题 int 城校 有意思 ay coordinate ax


前几天参加西安葡萄城的校招面试,发挥挺拉跨的,但没想到一面还是过了,当时面试官问了我一个面试题,感觉挺有意思的,在这记录一下,并手动实现。

问题:
给n个窗口的打开顺序,然后每个窗口的左上角顶点的坐标,和宽高,还有一个光标的坐标。问光标所在位置是哪个窗口,并且这个窗口的可视面积?(窗口与窗口之间重叠后,后打开的窗口会把先打开的窗口覆盖)

问题一找到光标在哪一个窗口?
思路:
根据给定的打开顺序,从后向前遍历,光标是否在当前窗口。

第二个问题求某个窗口的可视面积?
对某个窗口中的数据处理成矩形,用扫描线来做

代码:

//makefile
src = $(wildcard ./*.cpp)
obj = $(patsubst %.cpp, %.o, $(src))
target = app
CC = g++  
$(target): $(obj)
	$(CC) $(obj) -o $(target)

%.o: %.cpp
	$(CC) -c $< -o $@
.PHONY: clean
clean:
	rm -rf $(obj) $(target)
#include <algorithm>
#include <iostream>
#include <memory>
#include <unordered_map>
#include <vector>
#ifndef _VIEWARE_H_
#define _VIEWARE_H_
#define L INT_MIN
#define R INT_MAX
class Windows;
class Line;
class GetFillArea;
class Soultion;

class Windows {
 public:
  Windows() {}
  Windows(int windowsNums)
      : _windowsSize(windowsNums), _worldHeight(100), _worldWidth(100) {
    _worldIndex.first = _worldIndex.second = 0;
  }
  ~Windows() {}
  int _windowsSize;
  int _worldHeight;
  int _worldWidth;
  static std::vector<int> _coordinate;
  std::pair<int, int> _worldIndex;                 //世界坐标原点
  std::vector<std::vector<int>> _worldCoordinate;  //世界坐标点
  void setWindowsSize(int size) { this->_windowsSize = size; }
  void setWorldHeight(int heigth) { this->_worldHeight = heigth; }
  void setWorldWidth(int width) { this->_worldWidth = width; }
  void insertCoordinate(int x, int y, int width, int height);
  int findWindows(int x, int y);
  void buildPartialData(int windowsIndex);  //构造局部矩形内的数据
  void prPartia();
  std::vector<std::vector<int>> _partiaMatrix;
};

class Line {
 public:
  Line(int sx, int sty, int sdy, bool sfla)
      : x(sx), ty(sty), dy(sdy), fla(sfla) {}
  int x, ty, dy;
  bool fla;
  bool operator<(const Line& a) { return x < a.x; }
};

class GetFillArea {
 public:
  GetFillArea() {}
  std::unordered_map<int, int> Len, Lazy, Rson, Lson;
  std::vector<Line> line;
  std::vector<int> _axis;
  void prepareData(std::vector<std::vector<int>>& matrix);
  void buildTree(int k, int Ls, int Rs);
  void updateInterval(int k, int l, int r, int w);
  void pushUp(int k);
  int getFillArea();
  bool isfill = false;
};

class Soultion {
 public:
  Soultion(){};
  int getViewArea(std::vector<std::vector<int>>& Matrix,int x,int y);
};
#endif
#include "Viewarea.h"
std::vector<int> Windows::_coordinate(4, 0);

void Windows::insertCoordinate(int x, int y, int width, int height) {
  this->_coordinate[0] = x;
  this->_coordinate[1] = y;
  this->_coordinate[2] = x + width;
  this->_coordinate[3] = y + height;
  this->_worldCoordinate.push_back(_coordinate);
}

int Windows::findWindows(int x, int y) {
  int Index = -1;
  for (int i = this->_worldCoordinate.size() - 1; i >= 0; i--) {
    if (x >= _worldCoordinate[i][0] && y >= _worldCoordinate[i][1] &&
        x <= _worldCoordinate[i][2] && y <= _worldCoordinate[i][3]) {
      return i;
    }
  }
  return Index;
}

void Windows::buildPartialData(int windowsindex) {
  int _ax = this->_worldCoordinate[windowsindex][0];
  int _ay = this->_worldCoordinate[windowsindex][1];

  int _dx = this->_worldCoordinate[windowsindex][2];
  int _dy = this->_worldCoordinate[windowsindex][3];

  int _bx = _dx;
  int _by = _ay;

  int _cx = _ax;
  int _cy = _dy;

  for (int i = windowsindex + 1; i < this->_worldCoordinate.size(); i++) {
    int ax = this->_worldCoordinate[i][0];
    int ay = this->_worldCoordinate[i][1];

    int dx = this->_worldCoordinate[i][2];
    int dy = this->_worldCoordinate[i][3];

    int bx = dx;
    int by = ay;

    int cx = ax;
    int cy = dy;

    bool isA, isB, isC, isD;
    int vertex = 0;
    isA = isB = isC = isD = false;
    if (ax >= _ax && ay >= _ay && ax <= _dx && ay <= _dy) {
      isA = true;
      vertex++;
    }

    if (bx >= _ax && by >= _ay && bx <= _dx && by <= _dy) {
      isB = true;
      vertex++;
    }

    if (cx >= _ax && cy >= _ay && cx <= _dx && cy <= _dy) {
      isC = true;
      vertex++;
    }

    if (dx >= _ax && dy >= _ay && dx <= _dx && dy <= _dy) {
      isD = true;
      vertex++;
    }

    if (!vertex) {
      continue;
    } else if (vertex == 1) {
      if (isA) {
        this->_coordinate[0] = ax;
        this->_coordinate[1] = ay;
        this->_coordinate[2] = _dx;
        this->_coordinate[3] = _dy;
      } else if (isB) {
        this->_coordinate[0] = _cx;
        this->_coordinate[1] = by;
        this->_coordinate[2] = bx;
        this->_coordinate[3] = _cy;
      } else if (isC) {
        this->_coordinate[0] = cx;
        this->_coordinate[1] = _by;
        this->_coordinate[2] = _bx;
        this->_coordinate[3] = cy;
      } else if (isD) {
        this->_coordinate[0] = _ax;
        this->_coordinate[1] = _ay;
        this->_coordinate[2] = dx;
        this->_coordinate[3] = dy;
      }
      this->_partiaMatrix.push_back(this->_coordinate);
    } else if (vertex == 2) {
      if (isA && isB) {
        this->_coordinate[0] = ax;
        this->_coordinate[1] = ay;
        this->_coordinate[2] = bx;
        this->_coordinate[3] = std::min(dy, _dy);
      } else if (isC && isD) {
        this->_coordinate[0] = cx;
        this->_coordinate[1] = std::max(ay, _ay);
        this->_coordinate[2] = dx;
        this->_coordinate[3] = dy;
      } else if (isA && isC) {
        this->_coordinate[0] = ax;
        this->_coordinate[1] = ay;
        this->_coordinate[2] = std::min(dx, _dx);
        this->_coordinate[3] = cy;
      } else if (isB && isD) {
        this->_coordinate[0] = std::max(ax, _ax);
        this->_coordinate[1] = ay;
        this->_coordinate[2] = dx;
        this->_coordinate[3] = dy;
      } else {
        this->_coordinate[0] = ax;
        this->_coordinate[1] = ay;
        this->_coordinate[2] = dx;
        this->_coordinate[3] = dy;
      }
      this->_partiaMatrix.push_back(this->_coordinate);
    } else {
      this->_coordinate[0] = ax;
      this->_coordinate[1] = ay;
      this->_coordinate[2] = dx;
      this->_coordinate[3] = dy;
      this->_partiaMatrix.push_back(this->_coordinate);
    }
  }
}

void Windows::prPartia() {
  for (auto x : this->_partiaMatrix) {
    std::cout << x[0] << ' ' << x[1] << ' ' << x[2] << ' ' << x[3] << std::endl;
  }
}

void GetFillArea::prepareData(std::vector<std::vector<int>>& matrix) {
  for (auto& Matrix : matrix) {
    Line lf(Matrix[0], Matrix[1], Matrix[3], true);
    Line ls(Matrix[2], Matrix[1], Matrix[3], false);
    this->line.push_back(lf);
    this->line.push_back(ls);
    this->_axis.push_back(Matrix[1]);
    this->_axis.push_back(Matrix[3]);
  }
  if (matrix.empty()) {
    isfill = true;
    return;
  }
  sort(line.begin(), line.end());
  sort(_axis.begin(), _axis.end());

}

void GetFillArea::pushUp(int k) {
  if (Lazy[k]) {
    Len[k] = Rson[k] - Lson[k];
  } else {
    Len[k] = Len[k << 1] + Len[k << 1 | 1];
  }
}

void GetFillArea::buildTree(int k, int Ls, int Rs) {
  Lson[k] = _axis[Ls - 1], Rson[k] = _axis[Rs - 1];
  if (Rs - Ls <= 1) {
    return;
  }
  int MID = (Ls + Rs) >> 1;
  buildTree(k << 1, Ls, MID);
  buildTree(k << 1 | 1, MID, Rs);
}

void GetFillArea::updateInterval(int k, int l, int r, int w) {
  if (Lson[k] >= l && Rson[k] <= r) {
    Lazy[k] += w;
    pushUp(k);
    return;
  }

  if (Rson[k << 1] > l) {
    updateInterval(k << 1, l, r, w);
  }

  if (Lson[k << 1 | 1] < r) {
    updateInterval(k << 1 | 1, l, r, w);
  }

  pushUp(k);
}

int GetFillArea::getFillArea() {
  int fillareas = 0;

  if (isfill) {
    return fillareas;
  }

  buildTree(1, 1, _axis.size());
  for (int i = 0; i < this->line.size() - 1; i++) {
    int pw = line[i].fla ? 1 : -1;
    updateInterval(1, line[i].ty, line[i].dy, pw);
    fillareas += Len[1] * (line[i + 1].x - line[i].x);
  }
  return fillareas;
}

int Soultion::getViewArea(std::vector<std::vector<int>>& Matrix, int x, int y) {
  std::shared_ptr<Windows> windows = std::make_shared<Windows>(Matrix.size());
  std::shared_ptr<GetFillArea> getfill = std::make_shared<GetFillArea>();
  for (auto pos : Matrix) {
    windows->insertCoordinate(pos[0], pos[1], pos[2], pos[3]);
  }
  int _index = windows->findWindows(x, y);
  int allAreas = abs(windows->_worldCoordinate[_index][0] -
                     windows->_worldCoordinate[_index][2]) *
                 abs(windows->_worldCoordinate[_index][1] -
                     windows->_worldCoordinate[_index][3]);
  windows->buildPartialData(_index);
  getfill->prepareData(windows->_partiaMatrix);
  return allAreas - getfill->getFillArea();
}
#include <iostream>
#include <memory>

#include "Viewarea.h"

int main() {
  std::shared_ptr<Soultion> soultion = std::make_shared<Soultion>();
  /*测试数据*/
  std::vector<std::vector<int>> Matrix = {{1, 1, 3, 3}, {1, 1, 1, 1},
                                          {1, 3, 1, 2}, {3, 2, 2, 2},
                                          {4, 4, 2, 2}, {2, 2, 5, 5}};
  /*光标所在位置*/
  int gx, gy;
  gx = 4, gy = 1;

  std::cout << "ViewArea: " << soultion->getViewArea(Matrix, gx, gy) << std::endl;

  return 0;
}

标签:std,worldCoordinate,面试题,int,城校,有意思,ay,coordinate,ax
来源: https://blog.csdn.net/yangzijiangac/article/details/120514056

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有