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

Problem A. gRanks

Problem B. gFiles

Problem C. gGames

Problem D. gMatrix


1. 这个题,思路很直接,把每个人的得分算一下,然后相同的,按字母表排序输出(其实直接往map里插就好了,自动排序号)。记得名次要稍微注意下,就没了。


2. 这个题根据算式是可以算出上下限的,然后不断收缩上下限,看能不能确定唯一的数量,要注意的是,如果进度是100%就直接输出!


3. 这个题如果能想出关键的一步减枝,就不难了,否则非常难。。。

正确思路如下:

先建立一个树状结构,毕竟题目最多也就16个叶子节点。

然后放顺序,如果不减枝,小数据有8!种序列,大数据有16!种序列。

暴力是可以做小数据的

对于大数据,因为数字是从左往右放的,所以一个数字如果放在右枝,并且左枝是空的话,说明这个数字之前放过左枝,而现在把这个数字放在右枝是一种重复

同理,如果一个数字放在左枝,往上找父亲,如果父亲是右枝,并且左枝是空的话,说明这个数字之前已经放过了,重复,所以不放这个数字,如果父亲是左枝,就再往上找。

综合,放一个数字进叶子时,如果叶子是右枝且左枝为空就不放,否则对这个叶子节点的父亲做同样的检测。。。重复这个过程,就形成了最关键的一步减枝!

为什么是对的,做完这道题就明白了。。。(lz也是忽然脑洞大开)


4.

这个最后一题其实挺简单,真应该和第三题换换……

基本思想就是建立一个新的矩阵,最终让这个矩阵的每个节点存储以这个节点为左上角的正方形的最大值。

具体先一列列的压缩,再一行行的压缩。 比如

11 11 24

13 13 26

14 14 27

先压缩成

13 13 26

14 14 27

再压缩成

13 26

14 27

求和等于80

具体看了代码就明白了,非常好理解……

当然,不一定是最优的,lz没有去看高手是怎么做的


最后,附上代码

#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 P, M, N;
	vector<int> points;
	struct competition
	{
		int ratio;
		vector<string> players;
		competition(){ ratio = 0; }
	};

	vector<competition> competitions;
	map<string, vector<int>> playerScores;



	void SingleProcess(ofstream& fout)
	{
		playerScores.clear();
		for (int i = 0; i < competitions.size(); i++)
		{
			for (int j = 0; j < competitions[i].players.size(); j++)
			{
				playerScores[competitions[i].players[j]].push_back(competitions[i].ratio*points[j]);
			}
		}

		map<int, map<string, int>> ranks;
		for (map<string, vector<int>>::iterator iter = playerScores.begin(); iter != playerScores.end(); iter++)
		{
			int totalScore = 0;
			sort(iter->second.begin(), iter->second.end());
			reverse(iter->second.begin(), iter->second.end());
			
			for (int i = 0; i<iter->second.size()&&i<M;i++)
			{
				totalScore += iter->second[i];
			}
			ranks[totalScore][iter->first] = 1;
		}

		int count = 1;
		int rank = 1;
		
		map<int, map<string, int>>::iterator iter = ranks.end();
		iter--;
		for (; iter != ranks.end(); iter--)
		{
			for (map<string, int>::iterator it2 = iter->second.begin(); it2 != iter->second.end(); it2++)
			{
				fout << "\n" << rank << ": " << it2->first.c_str();
				count++;
			}
			rank = count;
		}

	}

	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", &P);
			points.resize(P, 0);
			for (int i = 0; i < P; i++)
			{
				scanf("%d", &points[i]);
			}

			scanf("%d", &N);
			competitions.clear();
			competitions.resize(N, competition());
			for (int i = 0; i < N; i++)
			{
				competitions[i].players.resize(P, "");
				scanf("%d", &competitions[i].ratio);
				char ch[256];
				for (int j = 0; j < P; j++)
				{
					scanf("%s", ch);
					competitions[i].players[j] = ch;
				}
			}

			scanf("%d", &M);

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

class PB
{
public:
	PB(){}
	int N;
	vector<vector<ll>> lines;

	void SingleProcess(ofstream& fout)
	{
		ll total;
		ll upper, lower;
		upper = 0x7fffffffffffffff;
		lower = 0;

		for (int i = 0; i < lines.size(); i++)
		{
			ll ct = lines[i][1] * 100;
			ll cp = lines[i][0];
			//没有101,注意
			if (cp == 100)
			{
				fout << ct / 100;
				return;
			}
			if (cp != 0)
			{
				if (ct%cp == 0) upper = min(upper, ct / cp);
				else upper = min(upper, ct / cp);
			}

			
			cp++;
			if (ct%cp == 0) lower = max(lower, ct / cp + 1);
			else lower = max(lower, ct / cp + 1);
		}

		if (lower == upper) fout << lower;
		else fout << -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++)
		{
			scanf("%d", &N);
			lines.resize(N, vector<ll>(2, 0));
			for (int i = 0; i < N; i++)
			{
				scanf("%lld %lld", &lines[i][0], &lines[i][1]);
			}

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

class PC
{
public:
	PC(){}
	int N, M;
	struct Elf
	{
		int id;
		vector<int> friends;
		int round;
		Elf()
		{
			id = -1;
			round = 0;
			friends.clear();
		}
	};

	Elf elfs[16];

	struct TreeNode
	{
		TreeNode* parent;
		TreeNode* leftChild;
		TreeNode* rightChild;
		vector<int> ids;
		int round;
		TreeNode()
		{
			parent = leftChild = rightChild = 0;
			round = 0;
			ids.clear();
		}
	};

	TreeNode leafs[16];
	TreeNode* head;

	void BuildTree()
	{
		queue<TreeNode*> levels;
		for (int i = 0; i < 16; i++)
		{
			levels.push(&leafs[i]);
		}
		int total = levels.size();
		int current = 0;
		while (levels.size()>1)
		{
			TreeNode* tn = new TreeNode();
			tn->leftChild = levels.front();
			levels.front()->parent = tn;
			levels.pop();
			tn->rightChild = levels.front();
			tn->round = levels.front()->round + 1;
			levels.front()->parent = tn;
			levels.pop();
			levels.push(tn);
		}
	}

	void resetTree(TreeNode* tn)
	{
		tn->ids.clear();
		if (tn->leftChild) resetTree(tn->leftChild);
		if (tn->rightChild) resetTree(tn->rightChild);
	}

	bool isFriend(Elf *e, int id2)
	{
		for (int i = 0; i < e->friends.size(); i++)
		{
			if (e->friends[i] == id2) return true;
		}
		return false;
	}

	bool checkConflict(vector<int>& vec, int t, int round)
	{
		Elf* e = &elfs[t];
		for (int i = 0; i < vec.size(); i++)
		{
			Elf* e2 = &elfs[vec[i]];
			if ((e->round >= round&&isFriend(e, e2->id)) || (e2->round >= round&&isFriend(e2, e->id)))
			{
				return true;
			}
		}
		return false;
	}

	bool findone = false;

	void DFS(int depth)
	{
		if (findone) return;
		/*for (int i = 0; i < N; i++)
		{
		if (leafs[i].ids.size() == 0) printf("%d ", 0);
		else printf("%d ", leafs[i].ids[0]+1);
		}
		printf("\n");*/
		if (depth == N)
		{
			findone = true;
			return;
		}

		for (int i = 0; i < N; i++)
		{
			if (findone) return;
			TreeNode* t = &leafs[i];
			if (t->ids.size()>0) continue;
			while (t != head&&t == t->parent->leftChild)
			{
				t = t->parent;
			}
			if (t != head&&t->parent->ids.size() == 0) continue;

			t = &leafs[i];
			bool conf = false;
			while (t != head->parent)
			{
				if (checkConflict(t->ids, depth, t->round))
				{
					conf = true;
					break;
				}
				t = t->parent;
			}
			if (conf) continue;

			t = &leafs[i];
			while (t != head->parent)
			{
				t->ids.push_back(depth);
				t = t->parent;
			}

			DFS(depth + 1);

			t = &leafs[i];
			while (t != head->parent)
			{
				t->ids.pop_back();
				t = t->parent;
			}
		}
	}

	string SingleProcess()
	{
		findone = false;
		DFS(0);
		if (findone) return "YES";
		return "NO";
	}

	void run()
	{
		FILE* fp = freopen("in.txt", "r", stdin);
		ofstream fout("out.txt");
		int Cases = 0;
		scanf("%d", &Cases);
		BuildTree();

		for (int time = 0; time < Cases; time++)
		{
			scanf("%d %d", &N, &M);
			head = &leafs[0];
			for (int i = 0; i < N; i++)
			{
				head = head->parent;
			}
			resetTree(head);
			N = pow(2, N);
			for (int i = 0; i < N; i++)
			{
				elfs[i].friends.clear();
				elfs[i].id = i;
				elfs[i].round = 0;
			}
			for (int i = 0; i < M; i++)
			{
				int e, k, b;
				scanf("%d %d %d", &e, &k, &b);
				elfs[e - 1].friends.resize(b, 0);
				elfs[e - 1].round = k;
				for (int j = 0; j < b; j++)
				{
					scanf("%d", &elfs[e - 1].friends[j]);
					elfs[e - 1].friends[j]--;
				}
			}


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

class PD
{
public:
	PD(){}
	int N, K, C, X;
	vector<vector<int>> matrix;
	void SingleProcess(ofstream& fout)
	{
		vector<vector<int>> k_matrix(N, vector<int>(N, 0));
		map<int,int> smap;
		map<int, int>::iterator iter;
		//竖着刷
		for (int col = 0; col < N; col++)
		{
			smap.clear();
			for (int row = 0; row < N; row++)
			{
				if (row < K-1) smap[matrix[row][col]]++;
				else
				{
					smap[matrix[row][col]]++;
					k_matrix[row + 1 - K][col] = smap.rbegin()->first;
					iter = smap.find(matrix[row + 1 - K][col]);
					iter->second--;
					if (iter->second == 0) smap.erase(iter);
				}
			}
		}

		//横着刷
		for (int row = 0; row < N - K + 1; row++)
		{
			smap.clear();
			for (int col = 0; col < N; col++)
			{
				if (col < K-1) smap[k_matrix[row][col]]++;
				else
				{
					smap[k_matrix[row][col]]++;
					int temp = k_matrix[row][col + 1 - K];
					k_matrix[row][col + 1 - K] = smap.rbegin()->first;
					iter = smap.find(temp);
					iter->second--;
					if (iter->second == 0) smap.erase(iter);
				}
			}
		}

		ll ret = 0;
		int NK = N - K + 1;
		for (int i = 0; i < NK; i++)
		{
			for (int j = 0; j < NK; j++)
			{
				ret += k_matrix[i][j];
			}
		}
		fout << ret;
	}

	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 %d %d", &N, &K, &C, &X);
			vector<int> arrayA, arrayB;
			arrayA.resize(N, 0);
			arrayB.resize(N, 0);
			matrix.clear();
			matrix.resize(N, vector<int>(N, 0));
			for (int i = 0; i < N; i++)
			{
				scanf("%d", &arrayA[i]);
			}
			for (int i = 0; i < N; i++)
			{
				scanf("%d", &arrayB[i]);
			}

			for (int i = 0; i < N; i++)
			{
				for (int j = 0; j < N; j++)
				{
					matrix[i][j] = (arrayA[i] * (i + 1) + arrayB[j] * (j + 1) + C) % X;
				}
			}

			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、付费专栏及课程。

余额充值