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

Problem A. Googol String

Problem B. gCube

Problem C. gCampus

Problem D. gSnake


1. 这题不要被10的100次方吓到了,其实这题思路很简单,注意长度上S2=S1*2+1,所以先找到第k个数字属于S几,然后倒着找,如果数字在倒着的左串就不改变,在右串就等于左串对应位置的数字改变(0变1,1变0),在中间就等于0. 此题得解


2.这个题其实就是求k个数字的乘积的k次方根,因为有精度要求所以暴力解法精度不达标……,那么该怎么做呢,求log

利用log2 函数,可以轻松解出来。。。这里要注意stl默认的log是以e为底的,别搞错了


3.这个题,如果想把每两个节点的最短路径都求出来是不可能的,主要因为有可能有很多最短路径,时间相同但路不同,最典型的,考虑一个网格,从左上角到右下角有多少不同的最短路径?

那么换个思路,其实对任意两点,求出最短路径,用floyd 五行搞定,然后对于每条路,如果所需的时间大于最短路径所需时间,这条路就要删除,否则不删除。问题得解

注意题目可能会给先给一个 1到2有一条耗时为3的路,再给一个 1到2有一条耗时为4的路,初始化floyd矩阵时要注意取最小值


4.这道题时间来不及(被2017APAC虐的太惨,本打算赶在3周内刷完所有APAC...但我太高估自己了)

如果能通过APAC2017E,我会回来把它补上……(虽然我觉得希望渺茫。。。)


最后 附上代码

#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(){}
	ll K;

	int DFS(ll t, ll k)
	{
		ll m = (t - 1) / 2;
		if (m == k) return 0;
		if (m > k) return DFS(m, k);
		if (m < k) return DFS(m, m-(k-m))^1;
	}


	void SingleProcess(ofstream& fout)
	{
		long long t = 0;
		K--;
		while (K >= t)
		{
			t = t * 2 + 1;
		}
		int num=DFS(t, K);
		fout << num;
	}

	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("%lld", &K);


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

class PB
{
public:
	PB(){}
	int M, N;
	vector<int> dimensions;
	vector<vector<int>> queries;

	void SingleProcess(ofstream& fout)
	{
		double len = 1;
		for (int i = 0; i < queries.size(); i++)
		{
			len = 0;
			for (int l = queries[i][0]; l <= queries[i][1]; l++)
			{
				len += log2((double)dimensions[l]);
			}
			len = len / (queries[i][1] - queries[i][0] + 1);

			len = powl(2, len);

			fout << endl << setiosflags(ios::fixed) << setprecision(8) << len;
		}
	}

	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 %d", &N, &M);
			dimensions.clear();
			dimensions.resize(N, 0);
			queries.clear();
			queries.resize(M, vector<int>(2, 0));

			for (int i = 0; i < N; i++)
			{
				scanf("%d", &dimensions[i]);
			}

			for (int i = 0; i < M; i++)
			{
				scanf("%d %d", &queries[i][0], &queries[i][1]);
			}

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

class PC
{
public:
	PC(){}
	int M, N;
	vector<bool> efficientRoad;
	vector<vector<int>> roads;
	struct Node
	{
		int val;
		vector<pair<Node*,int>> connects;
		Node(){ val = 0; }
	};

	vector<int> visited;
	vector<Node> offices;
	map<int, map<int, int>> roadNoMap;
	vector<vector<int>> floydMatrix;

	void DFSFindPath(map<int, vector<int>>& paths, int curr)
	{
		map<int, vector<int>>::iterator iter = paths.find(curr);
		if (iter == paths.end()) return;

		for (int i = 0; i < iter->second.size(); i++)
		{
			int roadNo = roadNoMap[iter->first][iter->second[i]];
			efficientRoad[roadNo] = true;
			if (visited[iter->second[i]] == 0)
			{
				visited[iter->second[i]] = 1;
				DFSFindPath(paths, iter->second[i]);
			}
		}
	}


	void Dijkstra(int from, int to)
	{
		map<int, Node*> record;
		visited.clear();
		visited.resize(N, INT_MAX);
		record[0] = &offices[from];
		visited[from] = 0;
		map<int, vector<int>> paths;
		while (!record.empty())
		{
			if (record.begin()->first >= visited[to]) break;

			Node* curr = record.begin()->second;
			record.erase(record.begin());
			for (int i = 0; i < curr->connects.size(); i++)
			{
				pair<Node*, int>& pi = curr->connects[i];
				if (visited[curr->val] + pi.second < visited[pi.first->val])
				{
					visited[pi.first->val] = visited[curr->val] + pi.second;
					record[visited[curr->val] + pi.second] = pi.first;
					paths[pi.first->val].push_back(curr->val);
				}
			}
		}

		visited.clear();
		visited.resize(N, 0);
		DFSFindPath(paths, to);
	}

	void Floyd(ofstream& fout)
	{
		floydMatrix.clear();
		floydMatrix.resize(N, vector<int>(N, 1e9));
		for (int i = 0; i < roads.size(); i++)
		{
			floydMatrix[roads[i][0]][roads[i][1]] = min(roads[i][2], floydMatrix[roads[i][0]][roads[i][1]]); //好阴……
			floydMatrix[roads[i][1]][roads[i][0]] = floydMatrix[roads[i][0]][roads[i][1]];
		}

		for (int i = 0; i < N; i++)
		{
			floydMatrix[i][i] = 0;
		}

		for (int k = 0; k < N; k++)
		{
			for (int i = 0; i < N; i++)
			{
				for (int j = 0; j < N; j++)
				{
					floydMatrix[i][j] = min(floydMatrix[i][k] + floydMatrix[k][j], floydMatrix[i][j]);
				}
			}
		}

		for (int i = 0; i < roads.size(); i++)
		{
			if (floydMatrix[roads[i][0]][roads[i][1]] < roads[i][2]) fout << "\n" << i;
		}
	}


	void SingleProcess(ofstream& fout)
	{
		Floyd(fout);
	}

	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 %d", &N, &M);
			roads.clear();
			roads.resize(M, vector<int>(3, 0));
			for (int i = 0; i < M; i++)
			{
				scanf("%d %d %d", &roads[i][0], &roads[i][1], &roads[i][2]);
			}


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

class PD
{
public:
	PD(){}
	int R, C;

	set<pair<int, int>> visited;

	struct snake
	{
		list<pair<int, int>> keyBody;
		int length;
		pair<int, int> headDir;

		snake(){}

		void init(int r, int c)
		{
			keyBody.clear();
			keyBody.push_back(make_pair(r, c));
			length = 1;
			headDir.first = 0;
			headDir.second = 1;
		}

		void moveOneStep(set<pair<int,int>>& visited,int R,int C)
		{
			int nr = keyBody.back().first + headDir.first;
			int nc = keyBody.back().second + headDir.second;
			nr %= R;
			nc %= C;
			if ((nr + nc) % 2 != 0 && visited.find(make_pair(nr, nc)) == visited.end())
			{
				keyBody.back().first = nr;
				keyBody.back().second = nc;
				visited.insert(keyBody.back());
			}
			else
			{
				keyBody.back().first = nr;
				keyBody.back().second = nc;

			}
		}

	};

	void SingleProcess(ofstream& fout)
	{
		
	}

	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 %d", &M, &N);


			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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值