谷歌中国算法比赛解题报告 APAC2015C

Problem A. Minesweeper

Problem B. Taking Metro

Problem C. Broken Calculator

Problem D. Tetris


这次的题侧重考工程了,其实每道题都不算难,就是麻烦……

1.扫雷,这道题思路很简单,首先把空白都点了,因为空白会打开周围8个格子,当没有空白可点的时候,再把没有点开的格子都点开就行了,点空白时dfs,或bfs开周围格子都可以


2.这题其实不难,但是非常麻烦,lz的做法就是把该定义的都定义好……

没事各位可以自己练练,感觉没啥好讲的

要注意的是,如果要乘车,才需要加等车时间,如果不乘车只是过个通道(比如地铁1的A站连着地铁2的B站,而B站连着地铁3的C站,那么从A站走去C站是不用乘车的)不加等车时间


3.这个题,首先发现了如果一个数字能直接打出来,那么按键的次数一定比用乘法少或相等,所以能打出来就不用DFS分解这个数字找相乘

然后对于一个数字,比如20,先看能不能打出来,不能打出来就找它大于1的因数,比如2,10,查看2,10能不能打出来,再查看4,5能不能打出来,然后储存按键的最小值,注意为了避免重复计算,比如20能打出来,就把20和对应的最少按键次数存下来,下次分解到20就可以直接输出了(比如80=2*40时40如果再分解成2*20找了次20,后来80=4*20时还会找20,这是20存储了,直接输出就好)


4.这个题依然是模拟题,对于每个方块,如果往下掉会跟当前形状冲突,就把他往上一格(如果方块还没下落那就game over),放到当前形状中,然后使用vertor.erase 删掉满了的行(偷懒方法,虽然效率低但是对着题足够了),再push_back一个新行。

依然,都定义好了就不难了,但是麻烦,毕竟模拟题基本上都是考工程……


最后。附上代码

#include <stdio.h>
#include <iostream>
#include <fstream>
#include <math.h>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <hash_map>
#include <hash_set>
#include <unordered_map>
#include <unordered_set>
#include <string.h>
#include <queue>
#include <list>
#include <iomanip>

using namespace std;

#define ll long long


class PA
{
public:
	PA(){}
	int N;
	vector<vector<int>> board;
	vector <vector<bool>> reveal;
	void addNumber(int row, int col)
	{
		if (row >= 0 && row < N&&col >= 0 && col < N)
		{
			if (board[row][col]!=-1)
				board[row][col]++;
		}
	}

	bool checkVaild(int row, int col)
	{
		if (row >= 0 && row < N&&col >= 0 && col < N) 
		{
			return true;
		}
		return false;
	}

	vector<pair<int, int>> revealNeighbors(pair<int, int> pi)
	{
		vector<pair<int, int>> ret;
		if (checkVaild(pi.first - 1, pi.second - 1) && reveal[pi.first-1][pi.second-1]==false) ret.push_back(pair<int, int>(pi.first - 1, pi.second - 1));
		if (checkVaild(pi.first - 1, pi.second) && reveal[pi.first - 1][pi.second] == false) ret.push_back(pair<int, int>(pi.first - 1, pi.second));
		if (checkVaild(pi.first - 1, pi.second + 1) && reveal[pi.first - 1][pi.second +1] == false) ret.push_back(pair<int, int>(pi.first - 1, pi.second + 1));
		if (checkVaild(pi.first, pi.second - 1) && reveal[pi.first][pi.second - 1] == false) ret.push_back(pair<int, int>(pi.first, pi.second - 1));
		if (checkVaild(pi.first, pi.second + 1) && reveal[pi.first][pi.second + 1] == false) ret.push_back(pair<int, int>(pi.first, pi.second + 1));
		if (checkVaild(pi.first + 1, pi.second - 1) && reveal[pi.first + 1][pi.second - 1] == false) ret.push_back(pair<int, int>(pi.first + 1, pi.second - 1));
		if (checkVaild(pi.first + 1, pi.second) && reveal[pi.first + 1][pi.second] == false) ret.push_back(pair<int, int>(pi.first + 1, pi.second));
		if (checkVaild(pi.first + 1, pi.second + 1) && reveal[pi.first +1][pi.second + 1] == false) ret.push_back(pair<int, int>(pi.first + 1, pi.second + 1));
		for (int i = 0; i < ret.size(); i++)
		{
			reveal[ret[i].first][ret[i].second] = true;
		}
		return ret;
	}

	int SingleProcess()
	{
		int click = 0;
		for (int i = 0; i < N; i++)
		{
			for (int j = 0; j < N; j++)
			{
				if (board[i][j] == -1)
				{
					addNumber(i - 1, j-1);
					addNumber(i - 1, j);
					addNumber(i - 1, j+1);
					addNumber(i, j+1);
					addNumber(i, j-1);
					addNumber(i + 1, j-1);
					addNumber(i + 1, j);
					addNumber(i + 1, j+1);
				}
			}
		}
		reveal.clear();
		reveal.resize(N, vector<bool>(N, false));
		//click 0
		for (int i = 0; i < N; i++)
		{
			for (int j = 0; j < N; j++)
			{
				if (board[i][j] == 0&&reveal[i][j]==false)
				{
					click++;
					reveal[i][j] = true;
					list<pair<int,int>> zeroList;
					zeroList.push_back(pair<int, int>(i, j));
					while (!zeroList.empty())
					{
						pair<int, int> pi = zeroList.front();
						zeroList.pop_front();
						vector<pair<int, int>> neighbor = revealNeighbors(pi);
						for (int k = 0; k < neighbor.size(); k++)
						{
							pair<int, int> cp = neighbor[k];
							if (board[cp.first][cp.second] == 0)
							{
								zeroList.push_back(cp);
							}
						}
					}
				}
			}
		}

		//check unvealed pos
		for (int i = 0; i < N; i++)
		{
			for (int j = 0; j < N; j++)
			{
				if (board[i][j] != -1 && reveal[i][j] == false) click++;
			}
		}




		return click;
	}

	void run()
	{
		FILE* fp = freopen("in.txt", "r", stdin);
		ofstream fout("out.txt");
		int Cases = 0;
		scanf("%d", &Cases);
		for (int time = 0; time < Cases; time++)
		{
			scanf("%d", &N);
			board.clear();
			board.resize(N, vector<int>(N, 0));
			for (int i = 0; i < N; i++)
			{
				char ch[1024];
				scanf("%s", &ch);
				for (int j = 0; j < N; j++)
				{
					if (ch[j] == '.') board[i][j] = 0;
					else board[i][j] = -1;
				}
			}

			fout << "Case #" << (time + 1) << ": " << SingleProcess() << endl;
			std::cout << time << endl;
		}
		fclose(fp);
		fout.close();
	}
};


class PB
{
public:
	PB(){}
	int M, N;

	

	struct tunnel
	{
		int metro1, metro2;
		int station1, station2;
		int time;
		tunnel()
		{
			metro1 = metro2 = station1 = station2 = 0;
		}

		bool getToMetroAndStation(int fromMetro, int& fromStation, int& toMetro, int &toStation)
		{
			if (fromMetro == metro1)
			{
				fromStation = station1;
				toMetro = metro2;
				toStation = station2;
			}
			else if (fromMetro==metro2)
			{
				fromStation = station2;
				toMetro = metro1;
				toStation = station1;
			}
			else return false;
			return true;
		}

		int getFromStation(int fromMetro)
		{
			if (fromMetro == metro1) return station1;
			if (fromMetro == metro2) return station2;
		}
	};
	
	vector<tunnel> allTunnel;

	struct metro
	{
		vector<int> station;
		vector<int> tunnels;

		vector<int> forwardTimes;
		vector<int> backwordTimes;
		int waiting;
		metro(){ waiting = 0; }
		void init()
		{
			int stationNumber = station.size() + 1;
			forwardTimes.resize(stationNumber, 0);
			forwardTimes[0] = 0;
			for (int i = 1; i < stationNumber; i++)
			{
				forwardTimes[i] = forwardTimes[i - 1] + station[i - 1];
			}

			backwordTimes.resize(stationNumber, 0);
			backwordTimes[stationNumber - 1] = 0;
			for (int i = stationNumber - 2; i >= 0; i--)
			{
				backwordTimes[i] = backwordTimes[i + 1] + station[i];
			}
		}

		vector<int> stationWithTunnels(int selfNo,vector<tunnel>& Alltunnel)
		{
			vector<int> ret;
			for (int i = 0; i < tunnels.size(); i++)
			{
				ret.push_back(Alltunnel[tunnels[i]].getFromStation(selfNo));
			}
			return ret;
		}

		int getTime(int stationStart, int stationEnd)
		{
			if (stationStart < stationEnd)
			{
				return forwardTimes[stationEnd] - forwardTimes[stationStart]+waiting;
			}
			else if (stationStart>stationEnd)
			{
				return backwordTimes[stationEnd] - backwordTimes[stationStart]+waiting;
			}
			return 0;
		}
	};

	vector<metro> allMetro;
	vector<vector<int>> queries;
	vector<vector<int>> visited;
	int minTime = 0;


	void DFS(int currMetro, int currStation, int endMetro, int endStation,int usedTime)
	{
		if (usedTime >= minTime) return;
		if (visited[currMetro][currStation]<=usedTime) return;

		visited[currMetro][currStation] = usedTime;

		if (currMetro == endMetro&&currStation == endStation)
		{
			minTime = usedTime;
			return;
		}

		if (currMetro == endMetro)
		{
			DFS(currMetro, endStation, endMetro, endStation, allMetro[currMetro].getTime(currStation, endStation) + usedTime);
		}

		vector<int>& tunnels = allMetro[currMetro].tunnels;
		for (int i = 0; i < tunnels.size(); i++)
		{
			int toS,ConnectM, ConnectS;
			allTunnel[tunnels[i]].getToMetroAndStation(currMetro, toS, ConnectM, ConnectS);
			DFS(ConnectM, ConnectS, endMetro, endStation, allMetro[currMetro].getTime(currStation, toS) + allTunnel[tunnels[i]].time+usedTime);
		}

	}



	int SingleProcess(ofstream& fout)
	{
		for (int i = 0; i < allMetro.size(); i++)
		{
			allMetro[i].init();
		}

		for (int i = 0; i < queries.size(); i++)
		{
			visited.clear();
			visited.resize(101, vector<int>(1001, INT_MAX));
			minTime = INT_MAX;
			DFS(queries[i][0]-1, queries[i][1]-1, queries[i][2]-1, queries[i][3]-1,0);
			if (minTime == INT_MAX) fout << -1 << endl;
			else fout << minTime << endl;
		}

		return 0;
	}

	void run()
	{
		FILE* fp = freopen("in.txt", "r", stdin);
		ofstream fout("out.txt");
		int Cases = 0;
		scanf("%d", &Cases);
		for (int time = 0; time < Cases; time++)
		{
			scanf("%d", &N);
			allMetro.clear();
			allMetro.resize(N, metro());
			for (int i = 0; i < N; i++)
			{
				int SN, W;
				scanf("%d %d", &SN, &W);
				allMetro[i].waiting = W;
				allMetro[i].station.resize(SN - 1, 0);
				for (int j = 0; j < SN-1; j++)
				{
					scanf("%d", &allMetro[i].station[j]);
				}
			}
			
			scanf("%d", &M);
			allTunnel.clear();
			allTunnel.resize(M, tunnel());
			for (int i = 0; i < M; i++)
			{
				scanf("%d %d %d %d %d", &allTunnel[i].metro1, &allTunnel[i].station1, &allTunnel[i].metro2, &allTunnel[i].station2, &allTunnel[i].time);
				allTunnel[i].metro1--;
				allTunnel[i].metro2--;
				allTunnel[i].station1--;
				allTunnel[i].station2--;
				allMetro[allTunnel[i].metro1].tunnels.push_back(i);
				allMetro[allTunnel[i].metro2].tunnels.push_back(i);
			}
			
			int Q;
			scanf("%d", &Q);
			queries.clear();
			queries.resize(Q, vector<int>(4,0));
			for (int i = 0; i < Q; i++)
			{
				scanf("%d %d %d %d", &queries[i][0], &queries[i][1], &queries[i][2], &queries[i][3]);
			}

			fout << "Case #" << (time + 1) << ": " << endl;
			SingleProcess(fout); 
			std::cout << time << endl;
		}
		fclose(fp);
		fout.close();
	}
};


class PC
{
public:
	PC(){}
	int X;
	bool isBroken[10];

	int pressNumber(int num)
	{
		int count = 0;
		while (num > 0)
		{
			int k = num % 10;
			if (isBroken[k]) return -1;
			count++;
			num = num / 10;
		}
		return count;
	}

	vector<int> numberAchivePress;

	int DFS(int num)
	{
		if (numberAchivePress[num] != INT_MAX) return numberAchivePress[num];

		int press = pressNumber(num);
		if (press > 0)
		{
			numberAchivePress[num] = press;
			return press;
		}

		int st = sqrt(num) + 1;
		int count = INT_MAX;
		for (int i = 2; i < st; i++)
		{
			if (num%i == 0)
			{
				if (DFS(i)>0 && DFS(num / i) > 0)
				{
					int temp = DFS(i) + DFS(num / i) + 1;
					if (temp < count) count = temp;
				}
			}
		}
		if (count == INT_MAX)
			numberAchivePress[num] = -1;
		else
			numberAchivePress[num] = count;
		return numberAchivePress[num];
	}

	void SingleProcess(ofstream& fout)
	{
		numberAchivePress.clear();
		numberAchivePress.resize(X + 1, INT_MAX);
		DFS(X);
		if (numberAchivePress[X] <=0) fout<<"Impossible";
		else fout << numberAchivePress[X]+1;
	}

	void run()
	{
		FILE* fp = freopen("in.txt", "r", stdin);
		ofstream fout("out.txt");
		int Cases = 0;
		scanf("%d", &Cases);
		for (int time = 0; time < Cases; time++)
		{
			for (int i = 0; i < 10; i++)
			{
				int temp;
				scanf("%d", &temp);
				if (temp == 1) isBroken[i] = false;
				else isBroken[i] = true;
			}
			scanf("%d", &X);

			fout << "Case #" << (time + 1) << ": ";
			SingleProcess(fout);
			fout<<endl;
			cout << time << endl;
		}
		fclose(fp);
		fout.close();
	}
};


class PD
{
public:
	PD(){}
	int W, H, N;

	vector<vector<char>> board;
	vector<vector<int>> blocks;


	struct tetromino
	{
		vector<vector<char>> box;
		int H, W;
		tetromino(){}
		void init(string A, int rows, int cols)
		{
			H = rows;
			W = cols;
			box.clear();
			box.resize(rows, vector<char>(cols, '.'));
			int count = 0;
			for (int i = rows-1; i >=0; i--)
			{
				for (int j = 0; j < cols; j++)
				{
					box[i][j] = A[count];
					count++;
				}
			}
		}
	};
	tetromino types[7][4];

	void preDefine()
	{
		//char S[7][4][4][5] = {
		//	"x...",
		//	"xx..",
		//	".x..",
		//	"....",
		//	".xx.",
		//	"xx..",
		//	"....",
		//	"....",
		//	"x...",
		//	"xx..",
		//	".x..",
		//	"....",
		//	".xx.",
		//	"xx..",
		//	"....",
		//	"....",
		//	".x..",
		//	"xx..",
		//	"x...",
		//	"....",
		//	"xx..",
		//	".xx.",
		//	"....",
		//	"....",
		//	".x..",
		//	"xx..",
		//	"x...",
		//	"....",
		//	"xx..",
		//	".xx.",
		//	"....",
		//	"....",
		//	"x...",
		//	"x...",
		//	"xx..",
		//	"....",
		//	"..x.",
		//	"xxx.",
		//	"....",
		//	"....",
		//	"xx..",
		//	".x..",
		//	".x..",
		//	"....",
		//	"xxx.",
		//	"x...",
		//	"....",
		//	"....",
		//	".x..",
		//	".x..",
		//	"xx..",
		//	"....",
		//	"xxx.",
		//	"..x.",
		//	"....",
		//	"....",
		//	"xx..",
		//	"x...",
		//	"x...",
		//	"....",
		//	"x...",
		//	"xxx.",
		//	"....",
		//	"....",
		//	"xx..",
		//	"xx..",
		//	"....",
		//	"....",
		//	"xx..",
		//	"xx..",
		//	"....",
		//	"....",
		//	"xx..",
		//	"xx..",
		//	"....",
		//	"....",
		//	"xx..",
		//	"xx..",
		//	"....",
		//	"....",
		//	"x...",
		//	"x...",
		//	"x...",
		//	"x...",
		//	"xxxx",
		//	"....",
		//	"....",
		//	"....",
		//	"x...",
		//	"x...",
		//	"x...",
		//	"x...",
		//	"xxxx",
		//	"....",
		//	"....",
		//	"....",
		//	".x..",
		//	"xxx.",
		//	"....",
		//	"....",
		//	".x..",
		//	"xx..",
		//	".x..",
		//	"....",
		//	"xxx.",
		//	".x..",
		//	"....",
		//	"....",
		//	"x...",
		//	"xx..",
		//	"x...",
		//	"...."
		//};
		types[0][0].init("x.xx.x", 3, 2);
		types[0][1].init(".xxxx.", 2, 3);
		types[0][2].init("x.xx.x", 3, 2);
		types[0][3].init(".xxxx.", 2, 3);

		types[1][0].init(".xxxx.", 3, 2);
		types[1][1].init("xx..xx", 2, 3);
		types[1][2].init(".xxxx.", 3, 2);
		types[1][3].init("xx..xx", 2, 3);

		types[2][0].init("x.x.xx", 3, 2);
		types[2][1].init("..xxxx", 2, 3);
		types[2][2].init("xx.x.x", 3, 2);
		types[2][3].init("xxxx..", 2, 3);

		types[3][0].init(".x.xxx", 3, 2);
		types[3][1].init("xxx..x", 2, 3);
		types[3][2].init("xxx.x.", 3, 2);
		types[3][3].init("x..xxx", 2, 3);

		types[4][0].init("xxxx", 2, 2);
		types[4][1].init("xxxx", 2, 2);
		types[4][2].init("xxxx", 2, 2);
		types[4][3].init("xxxx", 2, 2);

		types[5][0].init("xxxx", 4, 1);
		types[5][1].init("xxxx", 1, 4);
		types[5][2].init("xxxx", 4, 1);
		types[5][3].init("xxxx", 1, 4);

		types[6][0].init(".x.xxx", 2, 3);
		types[6][1].init(".xxx.x", 3, 2);
		types[6][2].init("xxx.x.", 2, 3);
		types[6][3].init("x.xxx.", 3, 2);
	}


	bool checkConflict(int drow, int dcol, tetromino& tet)
	{
		for (int row = 0; row < tet.H; row++)
		{
			for (int col = 0; col < tet.W; col++)
			{
				if (row + drow >= H) continue;
				if (board[row + drow][col + dcol] == 'x'&&tet.box[row][col] == 'x') return true;
			}
		}
		return false;
	}

	void putBlock(int drow, int dcol, tetromino& tet)
	{
		for (int row = 0; row < tet.H; row++)
		{
			for (int col = 0; col < tet.W; col++)
			{
				if (row + drow >= H) continue;
				if(tet.box[row][col]=='x') board[row + drow][col + dcol] = tet.box[row][col];
			}
		}
	}

	bool processBlock(vector<int> block)
	{
		tetromino tet = types[block[0]-1][block[1]];
		int dcol = block[2];
		int drow = 0;
		for (drow = H -1;; drow--)
		{
			if (drow<0)
			{
				//if (drow == H - 1) return false;
				drow++;
				if (drow + tet.H > H) return false;
				putBlock(drow, dcol, tet);
				break;
			}

			if (checkConflict(drow, dcol, tet))
			{
				//if (drow == H - 1) return false;
				drow++;
				if(drow + tet.H > H) return false;
				putBlock(drow,dcol, tet);
				break;
			}
		}


		//消除

		for (int row =0; row <H; row++)
		{
			bool full = true;
			for (int col = 0; col < W; col++)
			{
				if (board[row][col] == '.')
				{
					full = false;
					break;
				}
			}

			if (full)
			{
				board.erase(board.begin() + row, board.begin() + row + 1);
				board.push_back(vector<char>(W, '.'));
				row--;
			}
		}

		return true;
	}

	void SingleProcess(ofstream& fout)
	{
		for (int i = 0; i < blocks.size(); i++)
		{
			if (!processBlock(blocks[i]))
			{
				fout << endl<<"Game Over!";
				return;
			}
		}

		for (int i = H - 1; i >= 0;i--)
		{
			fout << endl;
			for (int j = 0; j < board[i].size(); j++)
			{
				fout << board[i][j];
			}
		}
	}

	void run()
	{
		FILE* fp = freopen("in.txt", "r", stdin);
		ofstream fout("out.txt");
		int Cases = 0;
		scanf("%d", &Cases);
		preDefine();
		for (int time = 0; time < Cases; time++)
		{
			scanf("%d %d %d", &W, &H, &N);
			board.clear();
			board.resize(H, vector<char>(W, '.'));
			blocks.resize(N, vector<int>(3, 0));
			for (int i = 0; i < N; i++)
			{
				scanf("%d %d %d", &blocks[i][0], &blocks[i][1], &blocks[i][2]);
			}

			fout << "Case #" << (time + 1) << ": ";
			SingleProcess(fout);
			fout << endl;
			std::cout << time << endl;
		}
		fclose(fp);
		fout.close();
	}
};






int main()
{
	//PA p;
	//PB p;
	//PC p;
	PD p;
	p.run();

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值