您的位置:首页 > 编程语言 > Go语言

Google Code jam Qualification Round 2015 解题报告

2015-04-12 10:20 417 查看
Problem A. Standing Ovation

题目说的是有许多观众,每个观众有一定的羞涩值,只有现场站起来鼓掌的人数达到该值才会站起来鼓掌,问最少添加多少羞涩值任意的人,才能使所有人都站起来鼓掌。

贪心模拟一下就好,添加的人默认让他们羞涩值为0,扫一遍,让加到刚好够就行。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <deque>

using namespace std;

char str[1010];

int main(){
	freopen("A-large.in","r",stdin);
	freopen("A-large.out","w",stdout);
	int t;
	cin>>t;
	int cas=0;
	while(t--){
		cas++;
		int MAX;
		cin>>MAX;
		scanf("%s",str);
		int len=strlen(str);
		
		int cnt=0;
		int ans=0;
		for(int i=0;i<len;i++){
			str[i]-='0';
			cnt+=str[i];
			if(cnt<i+1){
				int add = i+1-cnt;
				cnt+=add;
				ans+=add;
			}
		}
		printf("Case #%d: %d\n",cas,ans);
	}
	return 0;
}


Problem B. Infinite House of Pancakes

这个题很有意思。。说的是若干盘子上有一定量的食物,正常情况下,所有盘子上的食物每秒钟会减少1,或者你可以让某些秒变得特别,在特别的秒,盘子上的食物不会减少,但是你可以挑选一个有食物的盘子,移动部分或全部食物到另一个盘子上(空盘无限多)。目标是使所有食物尽快被吃完。
稍微分析一下,很容易得出这样一个结论,先分再吃,也就是说,早分一定不会比晚分差。然后很容易想到贪心去分割食物最多的盘子,分一半给空盘。其实这样是不对的。。比如只有一个食物为9的盘子,分成3,3,3比分成4,5要优。

我的解法是,首先只考虑只有一个盘子有食物的情况,dp预处理,dp(i,j)表示这个盘子有i个单位的食物,分为若干份,最大份食物量为j,至少需要多少次。

过了几天回来看了下,发现自己非常2B,直接分就行了。。为什么还要去dp。所以这个题就是枚举一下找出最小值。

然后就是贪心+枚举,先分再吃。枚举分的程度,即让所有盘子经过划分以后,食物最多的盘子不超过一个特定的值。详见代码。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <deque>
#include <set>
#include <queue>

using namespace std;

const int maxn = 1001;

int p[maxn];

int dp[maxn][maxn];

int main(){
	freopen("B-large.in","r",stdin);
	freopen("B-large.out","w",stdout);
	
	//dp预处理 
	for(int i=2;i<maxn;i++){
		for(int j=1;j<i;j++){
			dp[i][j]=1000;
			for(int k=1;k<i;k++){
				dp[i][j]=min(dp[i][j],dp[i-k][j]+dp[k][j]+1);
			}
		}
	}
	
	
	int t;
	cin>>t;
	
	for(int cas=1;cas<=t;cas++){
		int d;
		cin>>d;
		int MAX=0;
		for(int i=1;i<=d;i++){
			scanf("%d",&p[i]);
			MAX=max(MAX,p[i]);
		}
		int ans=MAX;
		//枚举。即把所有食物量大于test的盘子分为若干份,使得不再出现食物量大于test的盘子 
		for(int test=1;test<=MAX;test++){
			int tmp=0;
			for(int i=1;i<=d;i++){
				tmp+=dp[p[i]][test];
			}
			tmp+=test;
			ans=min(ans,tmp);
		}
		printf("Case #%d: %d\n",cas,ans);
	}
	return 0;
}


Problem C. Dijkstra

这个题我只暴力过了小数据,大数据没想清楚怎么做。贴一下暴力代码。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <deque>
#include <set>
#include <queue>

using namespace std;

/*
1-1
i-2
j-3
k-4
*/

int tab[5][5]={
	{ 0, 0, 0, 0, 0},
	{ 0, 1, 2, 3, 4},
	{ 0, 2,-1, 4,-3},
	{ 0, 3,-4,-1, 2},
	{ 0, 4, 3,-2,-1}
};

int calc(int a,int b){
	bool flag=0;
	if(a<0){
		a=-a;
		flag=!flag;
	}
	if(b<0){
		b=-b;
		flag=!flag;
	}
	int re=tab[a];
	if(flag)re=-re;
	return re;
}

char str[10010];
char re[10010][10010];

int main(){
	freopen("C-small-attempt0.in","r",stdin);
	freopen("C-small-attempt0.out","w",stdout);
	int t;
	cin>>t;
	int cas=0;
	while(t--){
		cas++;
		int l,x;
		cin>>l>>x;
		scanf("%s",str);
		for(int i=0;i<l;i++){
			if(str[i]=='i')str[i]=2;
			else if(str[i]=='j')str[i]=3;
			else str[i]=4;
		}
		for(int i=1;i<x;i++){
			for(int j=0;j<l;j++){
				str[i*l+j]=str[j];
			}
		}
		
		int tot=l*x;
		
		if(tot<3){
			printf("Case #%d: NO\n",cas);
			continue;
		}
		
		for(int i=0;i<tot;i++){
			re[i][i]=str[i];
			for(int j=i+1;j<tot;j++){
				re[i][j]=calc(re[i][j-1],str[j]);
			}
		}
		
		bool ok=false;
		for(int i=0;i<tot-2;i++){
			for(int j=tot-1;j>i+1;j--){
				if(re[0][i]==2&&re[j][tot-1]==4&&re[i+1][j-1]==3){
					ok=1;
				}
			}
		}
		
		if(ok){
			printf("Case #%d: YES\n",cas);
		}else{
			printf("Case #%d: NO\n",cas);
		}
	}
	return 0;
}


[b]Problem D.
Ominous Omino

小数据其实就64中case,用脑子想一下打表交就可以了。大数据真心不会做Orz。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: