Google APAC 2016 University Graduates Test Round A

Google APAC 2016 University Graduates Test Round A_第1张图片


今天手感还算不错,出了三个题,也有不顺的时候,要不第四题水个小数据或许可以混进前100。总的来说题目很简单,没有什么复杂的东西。


A - Googol String

       题意:

              目前只考虑包含'0','1'的字符串,有两个操作Switch与Reverse...其中Switch将其中的'0'变成'1','1'变成'0', Reverse将字符串反转

              定义:

                     S0=""

                     Sn=Sn-1+'0'+Switch(Reverse(Sn-1))

                     现在已知n=10的100次方,问第k(小于10的18次方)位是0还是1

       题解:

              其实看到k的范围就知道n这么大的范围只是一个幌子,当n到62的时候,位数已经突破10的18次方位了,所以我觉得两个思路来做,第一个先打表,然后download数据后跑结果,第二个就是我用的在线递归,注意到Sn的长度总是2的n次方-1...就不难写出递归的方法了...

       Code:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
#include <stack> 
#include <map>
using namespace std;
int dfs(long long k,long long h){
	if (k==((h-1)/2))
		return 0; 
    if (k<(h/2-1)) 
    	return dfs(k,h/2);
  	else{ 
  		k=h-2-k; 
  		return 1-dfs(k,h/2);
    }
}
int main(){
	freopen("A-small-attempt0.in.txt","r",stdin);
	freopen("output.txt","w",stdout);     
	int T;
	cin>>T;
	long long c=1;
	for (int i=1;i<=62;i++) c=c*2;   
	for (int cases=1;cases<=T;cases++){
		long long k;
		cin>>k;
		k--;
		cout<<"Case #"<<cases<<": "<<dfs(k,c)<<endl;
	}
	return 0;
}

B - gCube

       题意:

              直接点说就是求D个数之积开D次方的结果。

       题解:

              很容易想到用log来处理,因为用了log后原本的连乘变成了连加,最后再把结果还原就是。

       Code:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
#include <stack> 
#include <map>
using namespace std;
const int MAXN=100005;
int a[MAXN];
int main(){
	freopen("B-large.in.txt","r",stdin);
	freopen("output.txt","w",stdout);   
	int T;
	scanf("%d",&T);
	for (int cases=1;cases<=T;cases++){
		int n,m;
		scanf("%d%d",&n,&m);
		for (int i=0;i<n;i++) scanf("%d",&a[i]);
		printf("Case #%d:\n",cases);
		while (m--){
			int L,R,D;
			scanf("%d%d",&L,&R);
			D=(R-L+1);
			double ans=0;
			for (int i=L;i<=R;i++) ans+=log2(a[i]);
			ans/=D;
			printf("%.10lf\n",pow(2,ans));
		}
	}
	return 0;
}

C - gCampus

       题意:

              给一个图(点的个数小于100,边的个数小于10000),问其中有哪些边是不在任意一个两两间的最短路上的。

       题解:

              这个之前做过类似的,跑个floyd然后比较下即可..比较坑的是小数据..跑出结果后不敢提交有么有...

Google APAC 2016 University Graduates Test Round A_第2张图片

       Code:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
#include <stack> 
#include <map>
using namespace std;
const int MAXN=20005;
struct Edge{
	int u,v,c;
}edge[MAXN]; 
int dis[105][105];
int ABS(int x){
	if (x<0) return -x;
	return x;
}  
void Floyd(int n){
	for (int k=0;k<n;k++)
		for (int u=0;u<n;u++)
			for (int v=0;v<n;v++)
				if (dis[u][v]-dis[u][k]>dis[k][v])
					dis[u][v]=dis[u][k]+dis[k][v];
}
bool f[MAXN];
int main(){
	freopen("C-small-attempt0.in.txt","r",stdin);
	freopen("output.txt","w",stdout);   
	int T;
	scanf("%d",&T);
	for (int cases=1;cases<=T;cases++){
		int n,m;
		scanf("%d%d",&n,&m);  
		memset(dis,0x7f,sizeof(dis));
		for (int i=0;i<n;i++) dis[i][i]=0;
		for (int i=0;i<m;i++){
			int u,v,c;
			scanf("%d%d%d",&u,&v,&c);
			edge[i].u=u,edge[i].v=v,edge[i].c=c;
			dis[u][v]=min(dis[u][v],c);
			dis[v][u]=min(dis[v][u],c);
		} 
		printf("Case #%d:\n",cases);
		Floyd(n); 
		memset(f,false,sizeof(f));
		for (int s=0;s<n;s++)
			for (int t=0;t<n;t++)
				for (int k=0;k<m;k++)
					if (dis[s][edge[k].u]+edge[k].c+dis[edge[k].v][t]==dis[s][t])
						f[k]=true;
		for (int i=0;i<m;i++)
			if (!f[i]) printf("%d\n",i); //
	}
	return 0;
}


你可能感兴趣的:(Google APAC 2016 University Graduates Test Round A)