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

Problem A. Country Leader

Problem B. Rain

Problem C. Jane's Flower Shop

Problem D. Clash Royale


终于来到APAC2017了,lz作为一个找工作之前从没刷过题的研究僧,心情真是极为复杂,不过现在已经在某知名公司找到了游戏程序的工作,终于能正视这些题了,说实话,我也不知道自己为什么要在找到工作后还制定一个刷完APAC的计划,也许是连跪四次搞的自己自尊心受到了极大伤害吧。至于进谷歌去硅谷走上人生巅峰,白日梦做做就行了,毕竟没有像大牛那么努力,平常玩的太high。但是,我不后悔,至少我的大学,我过得很开心。


前言就此打住,让我们来看题


1. 这个题要注意 空格是参与排序但不参与计算的,我也记不得空格跟ABCD谁在前了不过扔进map里或sort一下就没错了


2.这道题的基本思路是,先假设每个格子都有INT_MAX的雨,然后先把边上的格子都还原成地形高度,然后dfs,如果相邻的格子比这个格子高,相邻的格子就取这个格子的值或地形高度值,每个边上的格子都dfs一遍后,再就剩下的雨水量就好了


3.一道二分查找题,题目说了-1到1之间只有一个解,所以没啥好说的,上限跟下限差小于10-9停止搜索就好了


4.一道比较难的动归题,但是如果熟悉了动归,这题不算难解。

这个题的变量有3个,金钱数,卡的战力值,卡的数量

组成的卡相等时,金钱数越低越好,战力值越高越好

所以这样组织数据结构, 第一维 卡数, 第二维 战力,第三维 钱数 (第二,三维也可以交换,第一维选卡数因为它数量级最小,8个)

必须要选8张卡

所以先建立9个map,用数组存,即vector<map<long long, int>> mmap;这里vector[1] 表示这个里面只放一张卡,vector[2]表示里面只放两张卡的各种组合。。。然后按顺序一张一张放vector[1]里的加上一张卡,这个组合就放进vector[2],注意测试每个加进去的组合是不是最优的,如果加进去的组合比原来的某些组合优,就删掉原来这些组合,如果原来有些组合比要加的组合优,就不加。


最后去vector[8]中最优的组合就好了


附上代码

#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>
#include <istream>
#include <string>

using namespace std;

#define ll long long
#define uint unsigned int


class PA
{
public:
	PA(){}
	int N;
	vector<string> names;
	
	void SingleProcess(ofstream& fout)
	{
		vector<string> ret;
		ret.push_back("");
		int chars[256];
		int maxCount = 0;
		for (int i = 0; i < names.size(); i++)
		{
			memset(chars, 0, sizeof(chars));
			int count = 0;
			for (int j = 0; j < names[i].length(); j++)
			{
				chars[names[i][j]]++;
			}
			for (int c = 'A'; c <= 'Z'; c++)
			{
				if (chars[c]>0) count++;
			}
			if (count>maxCount)
			{
				maxCount = count;
				ret.clear();
				ret.push_back(names[i]);
			}
			else if (count == maxCount)
			{
				ret.push_back(names[i]);
			}
		}
		sort(ret.begin(), ret.end());
		fout << ret[0].c_str();
	}

	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++)
		{
			string str;
			cin >> N;
			names.clear();
			names.resize(N);
			getline(cin, str);
			for (int i = 0; i < N; i++)
			{
				getline(cin, names[i]);	
			}

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

class PB
{
public:
	PB(){}
	int R, C;
	vector<vector<int>> height;
	vector<vector<int>> water;

	void DFS(int row, int col)
	{
		if (row > 0)
		{
			if (water[row - 1][col] > water[row][col])
			{
				water[row - 1][col] = max(water[row][col], height[row - 1][col]);
				DFS(row - 1, col);
			}
		}

		if (row <R-1)
		{
			if (water[row + 1][col] > water[row][col])
			{
				water[row + 1][col] = max(water[row][col], height[row + 1][col]);
				DFS(row + 1, col);
			}
		}

		if (col > 0)
		{
			if (water[row][col - 1] > water[row][col])
			{
				water[row][col - 1] = max(water[row][col], height[row][col - 1]);
				DFS(row, col - 1);
			}
		}

		if (col <C-1)
		{
			if (water[row][col + 1] > water[row][col])
			{
				water[row][col + 1] = max(water[row][col], height[row][col + 1]);
				DFS(row, col + 1);
			}
		}
	}

	void SingleProcess(ofstream& fout)
	{
		water.clear();
		water.resize(R, vector<int>(C, INT_MAX));
		for (int i = 0; i < R; i++)
		{
			water[i][0] = height[i][0];
			water[i][C - 1] = height[i][C - 1];
		}
		for (int i = 0; i < C; i++)
		{
			water[0][i] = height[0][i];
			water[R-1][i] = height[R-1][i];
		}

		for (int i = 0; i < R; i++)
		{
			DFS(i, 0);
			DFS(i, C - 1);
		}
		for (int i = 0; i < C; i++)
		{
			DFS(0,i);
			DFS(R-1, i);
		}

		ll total = 0;
		for (int i = 0; i < R; i++)
		{
			for (int j = 0; j < C; j++)
			{
				total += water[i][j] - height[i][j];
			}
		}
		fout << total;
	}

	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++)
		{
			cin>>R>>C;
			height.clear();
			height.resize(R, vector<int>(C, 0));
			for (int i = 0; i < R; i++)
			{
				for (int j = 0; j < C; j++)
				{
					cin >> height[i][j];
				}
			}

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

class PC
{
public:
	PC(){}
	int M;
	vector<ll> costs;
	ll value;
	void SingleProcess(ofstream& fout)
	{
		double lower = 0;
		double upper = 2;
		double threhold = 1e-10;
		costs[0] *= -1;
		while (abs(lower - upper) > threhold)
		{
			double mid = (lower + upper) / 2;
			double ans = 0;
			for (int i = 0; i < costs.size(); i++)
			{
				ans += powl(mid, M - i)*costs[i];
			}
			if (ans+value>0)
			{
				lower = mid;
			}
			else
			{
				upper = mid;
			}
		}
		upper -= 1;
		fout << setprecision(10) << fixed << upper;
	}

	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++)
		{
			cin>>M;
			costs.resize(M);
			for (int i = 0; i < M; i++)
			{
				cin >> costs[i];
			}
			cin >> value;

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

class PD
{
public:
	PD(){}
	int M, N;
	struct Card
	{
		int level;
		vector<int> power;
		vector<int> upgrade;
		Card(){ level = 0; }
	};

	struct INT3
	{
		int num, power, cost;
		INT3(){ num = power = cost = 0; }
	};

	Card cards[12];

	vector<map<long long, int>> mmap;
	map<long long, int>::iterator iter, iter2;

	long long SingleProcess()
	{
		mmap.clear();
		mmap.resize(9, map<long long, int>());
		mmap[0][0] = 0;
		for (int i = 0; i < N; i++)
		{
			Card& c = cards[i];
			for (int j = 7; j >= max(0, 8 - (N - i)); j--)
			{
				if (mmap[j].empty()) continue;
				for (iter = mmap[j].begin(); iter != mmap[j].end(); iter++)
				{
					int cost, num;
					cost = iter->second;
					long long power = iter->first;
					num = j + 1;
					for (int k = c.level; k < c.power.size(); k++)
					{
						if (k>c.level) cost += c.upgrade[k - 1];
						if (cost > M) break;
						power = iter->first + c.power[k];

						if (mmap[num].empty())
						{
							mmap[num][power] = cost;
							continue;
						}

						iter2 = mmap[num].end();
						iter2--;
						while (iter2 != mmap[num].end())
						{
							if (iter2->first >= power&&iter2->second <= cost)
							{
								break;
							}
							else if (iter2->first < power&&iter2->second >= cost)
							{
								mmap[num].erase(iter2--);
							}
							else iter2--;
						}
						if (iter2 == mmap[num].end())
						{
							mmap[num][power] = cost;
						}
					}
				}
			}
		}
		return mmap[8].rbegin()->first;
	}

	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);
			for (int i = 0; i < N; i++)
			{
				int K, L;
				scanf("%d %d", &K, &L);
				cards[i].level = L - 1;
				cards[i].power.resize(K, 0);
				cards[i].upgrade.resize(K - 1, 0);
				for (int j = 0; j < K; j++)
				{
					scanf("%d", &cards[i].power[j]);
				}
				for (int j = 0; j < K - 1; j++)
				{
					scanf("%d", &cards[i].upgrade[j]);
				}
			}

			fout << "Case #" << (time + 1) << ": " << SingleProcess() << 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、付费专栏及课程。

余额充值