zoukankan      html  css  js  c++  java
  • 牛客网-华为-2020届校园招聘上机考试-3

    题目描述
    小明在玩切水果游戏,已知屏幕上有若干水果,只允许用直线切水果,一次只允许划出一条直线,直线上的水果都会被消除掉;请求出小明最少要切多少次才能把屏幕上的水果都切掉。已知屏幕由40*50的小方格组成,经过每个方格划出的直线最多只有4条,如下图所示经过红色方格(标注为8)能划出直线最多为4条,其中相同数字的方格属于同一直线(0为空);屏幕左上角坐标为(0,0),右下角坐标为(39,49)。
    |4|0|0|1|0|0|3|
    |0|4|0|1|0|3|0|
    |0|0|4|1|3|0|0|
    |2|2|2|8|2|2|2|
    |0|0|3|1|4|0|0|
    |0|3|0|1|0|4|0|
    |3|0|0|1|0|0|4|

    输入描述
    第一行输入整数N(0<N<=36),接下来N行,每行两个整数X,Y(0<=X<40, 0<=Y<50)用空格隔开,表示水果所在方格的X坐标和Y坐标,不同水果的坐标一定不同,输入保证合法。
    输出描述
    程序输出一个整数并换行,表示小明需要切水果的最少次数。

    示例1
    输入
    2
    3 4
    2 2
    输出
    2

    1.思考

    • 本来是放弃第二题先做第三题的,结果发现第三题更难,只好硬着头皮写了……
    • 先用coor记录下所有水果的位置坐标;
    • 再用一个map表示每个位置的水果在横切、竖切、左上至右下切、右上至左下切四种方式下能够切到的其他的水果的id,这里的id直接就用输入先后顺序作为id;
    • 然后用一个count记录每个位置的水果在一刀下能切掉水果的最多数目;
    • 接着每次都选择能够切掉最多水果的那个位置下的那一刀,并将已经切掉的水果从coor记录中删除;
    • 之后依照新的coor记录重新建立map和count,重复上述过程,直至所有水果都消除。
    • 因为没有线上提交,所以不太清楚这个方案是否能通过所有的测试集。我主要困惑的是,每次选择能切掉最多水果的那一刀,是否能够保证最后用的次数是最少的,这一点还没有想通,所以有可能思路是错误的,代码也写的不对……

    2.实现

    #include <iostream>
    #include <vector>
    #include<algorithm>
    using namespace std;
    
    vector<vector<vector<int>>> map;
    
    void Hori(int index, vector<vector<int>> coor)
    {
    	vector<int> co = coor[index];
    	int len = coor.size();
    	for (int i = 0; i < len; i++){
    		if (i != index){
    			auto node = coor[i];
    			if (node[1] == co[1]){//same y label -
    				map[index][0].push_back(i);
    			}
    		}
    	}
    }
    
    void Vert(int index, vector<vector<int>> coor)
    {
    	vector<int> co = coor[index];
    	int len = coor.size();
    	for (int i = 0; i < len; i++){
    		if (i != index){
    			auto node = coor[i];
    			if (node[0] == co[0]){//same x label |
    				map[index][1].push_back(i);
    			}
    		}
    	}
    }
    
    void Left(int index, vector<vector<int>> coor)
    {
    	vector<int> co = coor[index];
    	int len = coor.size();
    	for (int i = 0; i < len; i++){
    		if (i != index){
    			auto node = coor[i];
    			if (node[0]-node[1]==co[0]-co[1]){//From top left to bottom right 
    				map[index][2].push_back(i);
    			}
    		}
    	}
    }
    
    void Right(int index, vector<vector<int>> coor)
    {
    	vector<int> co = coor[index];
    	int len = coor.size();
    	for (int i = 0; i < len; i++){
    		if (i != index){
    			auto node = coor[i];
    			if (node[0] + node[1] == co[0] + co[1]){//From top right to bottom left /
    				map[index][3].push_back(i);
    			}
    		}
    	}
    }
    
    //Calculate the max number of fruits when erase fruit i.
    void CalMaxCount(vector<int>& count)
    {
    	int n = map.size();
    	int maxc = 0;
    	for (int i = 0; i < n; i++){
    		auto m = map[i];
    		maxc = 0;
    		for (int j = 0; j < 4; j++){
    			int lm = m[j].size();
    			maxc = maxc>lm?maxc:lm;
    		}
    		count[i] = maxc;
    	}
    }
    
    vector<int> ConstMap(int n, vector<vector<int>>& coor)
    {
    	map.clear();
    
    	//initial map
    	vector<int> a;
    	vector<vector<int>> b;
    	for (int i = 0; i < 4; i++){
    		b.push_back(a);
    	}
    	for (int i = 0; i < n; i++){
    		map.push_back(b);
    	}
    
    	int lc = coor.size();
    	vector<int> count(n);
    	for (int i = 0; i < lc; i++){
    		Hori(i, coor);
    		Vert(i, coor);
    		Left(i, coor);
    		Right(i, coor);
    	}
    	CalMaxCount(count);
    
    	return count;
    }
    
    bool cmp(int a, int b)
    {
    	return a > b;
    }
    
    void CoorClear(int index, vector<vector<int>>& coor)
    {
    	int len = coor.size(), pos = 0, maxc = 0;
    	auto m = map[index];
    	for (int j = 1; j < 4; j++){
    		if ( m[j].size() > maxc ){
    			maxc = m[j].size();
    			pos = j;
    		}
    	}
    
    	vector<int> node = map[index][pos];
    	sort(node.begin(), node.end(), cmp);
    	for (int i = 0; i < maxc; i++){
    		coor.erase(coor.begin()+node[i]);
    	}
    	coor.erase(coor.begin() + index);
    }
    
    int main(){
    	int n;
    
    	while (cin>>n){
    		int x, y;
    		vector<vector<int>> coor;
    		vector<int> count(n);
    
    		//input coordinate
    		for (int i = 0; i < n; i++){
    			cin >> x >> y;
    			coor.push_back(vector<int> {x, y});
    		}
    
    		int res = 0, pos;
    		while(coor.size()){
    			//Construct Map
    			count = ConstMap(n, coor);
    
    			//Erase the line with most fruits.
    			pos = max_element(count.begin(), count.end()) - count.begin();
    			CoorClear(pos, coor);
    			res++;
    		}
    
    		cout << res<<endl;
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    linux 安装ssh以及ssh用法与免密登录
    linux下安装Tomcat和java jdk
    光盘文件的挂载和yum源配置
    linux常用命令
    使用样式更改多个控件的外观
    silverlight 控件初始化和布局
    XML的读写
    dataset对XML的操作。writexml() and readxml。dataset.AcceptChanges()。dataset.DIspose()。释放资源
    C# 结构体 struct
    C#操作XML小结(转)
  • 原文地址:https://www.cnblogs.com/xuyy-isee/p/10611465.html
Copyright © 2011-2022 走看看