谷歌校招笔试的练习赛,题目很简单,应该只是用来熟悉环境的
题目链接
A - Bad Horse
题意
有一些人,并且告诉一些二元关系,表示哪对人是不能属于一个组的,问可不可以将所有人分为两组。
题解
也就是给了一个图判断其可不可以表示为二分图了,根据二分图的性质知道存在奇圈的图就无法表示成,所以根据题意的二元关系作图后,找图中是否存在奇圈即可。
Code:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
#include <stack>
#include <map>
#define MAXN 305 //---
using namespace std;
struct edge{
int u,v,next;
}edge[MAXN];
map<string,int> H;
int En,_next[MAXN],dis[MAXN];
void addedge(int u,int v){
edge[++En].next=_next[u],_next[u]=En;
edge[En].u=u,edge[En].v=v;
}
bool dfs(int u,int l){
if (dis[u]!=-1){
if (dis[u]%2 == l%2) return true;
return false;
}
dis[u]=l;
for (int k=_next[u];k;k=edge[k].next){
int v=edge[k].v;
if (!dfs(v,l+1)) return false;
}
return true;
}
bool judge(int n){
memset(dis,-1,sizeof(dis));
for (int i=1;i<=n;i++)
if (dis[i]==-1){
if (!dfs(i,0)) return false;
}
return true;
}
int main(){
freopen("A-small-2-attempt0.in.txt","r",stdin);
freopen("output.txt","w",stdout);
int T;
cin>>T;
for (int cases=1;cases<=T;cases++){
int m,n=0;
memset(_next,0,sizeof(_next)),En=0;
cin>>m;
H.clear();
for (int i=1;i<=m;i++){
string s1,s2;
int u,v;
cin>>s1>>s2;
if (H.find(s1)==H.end()) H[s1]=++n;
if (H.find(s2)==H.end()) H[s2]=++n;
u=H[s1],v=H[s2];
addedge(u,v),addedge(v,u);
}
printf("Case #%d: ",cases);
if (judge(n)) puts("Yes");
else puts("No");
}
return 0;
}
B - Captain Hammer
题意
类似打企鹅,愤怒的小鸟之类的游戏,从(0,0)点以初始速度V抛出物体,已知重力加速度为9.8m/s^2,已知物体落地后停止移动,并且在X轴上前进了D米,问初始抛出时角度是多少。
题解
中学物理题,恶心的是直接用cmath的asin居然会WA…于是手写了个二分来求arcsin。
Code:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
#include <stack>
using namespace std;
const double PI=acos(-1.0);
const double eps=1e-10;
double aSin(double x){
double l=0,r=PI/2;
while (r-l>eps){
double mid=(l+r)/2;
if (sin(mid)<=x) l=mid;
else r=mid;
}
return l;
}
int main(){
freopen("B-small-attempt1.in.txt","r",stdin);
freopen("output.txt","w",stdout);
int T;
scanf("%d",&T);
for (int cases=1;cases<=T;cases++){
int V,D;
scanf("%d%d",&V,&D);
double ans=9.8*D/(V*V);
ans=aSin(ans);
printf("Case #%d: %.8f\n",cases,ans*90/PI);
}
return 0;
}
C - Moist
题意
有一堆写了人名的卡片放在一个栈中,希望让这个栈中所有卡片按照人名的ASCII码从栈顶到栈底排好序。而现在有一个机器人,它做的操作是每次从栈顶往栈底扫描,一旦发现有一个人名的ASCII码比之前扫过的要小,就话费1刀的代价将其放在栈顶到它这一段目前正确的位置,然后机器人再从栈顶往栈底扫描,直到这个栈排好序,问总共要话费多少刀。
题解
模拟
Code
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
#include <stack>
#include <map>
using namespace std;
const int MAXN=105;
string s[MAXN];
char str[105];
int main(){
freopen("C-small-2-attempt0.in.txt","r",stdin);
freopen("output.txt","w",stdout);
int T;
scanf("%d",&T);
for (int cases=1;cases<=T;cases++){
int n;
scanf("%d\n",&n);
for (int i=1;i<=n;i++) gets(str),s[i]=str;
int ans=0;
for (int t=2;t<=n;t++){
int i;
for (i=t;i<=n;i++)
if (s[i]<s[i-1]){
ans++;
break;
}
for (;i>=2;i--)
if (s[i]<s[i-1]) swap(s[i],s[i-1]);
}
printf("Case #%d: %d\n",cases,ans);
}
return 0;
}