2014 google (在线)测试笔试题解

题目说明

测试笔试有三道题目 A、B、C。C 题最简单,B 题次之,A 题有些困难,分值也是越简单的分值越少,but,比较简单的 B 题实际上却又最高分值 22 pt !(A 大小测试集分值分别是 21pt/12pt,C 大小测试集分值分别是 6pt/4pt。) 看来到时候题目未必要按照顺序做呀,最初大家都上来做 A 题,但又不能轻易搞定,时间耽误了,成绩却没有,O__O"…

题目说明都很长,但是实际上表达的意思或是抽象出来说明其实都很简单,下面就说题目到底是要干嘛:

  1. A : 有一些人,他们一些是冤家,现在给很多这样的“冤家对”,问给的这些人是否可以分成两组,每一组里面没有冤家,给出 Yes 或是 No !
  2. B : 将一个小球在地面上和水平面成 θ 角以速度 v 抛出,落地时抛出的水平距离是 D ,已知 v 和 D,求 θ。(重力加速度 g = 9.8 m/s2。) [喔屮,这完全就是一个高中物理题丫,有木有!]
  3. C : 有一系列数字,比如 2 3 4 1 5,从前向后扫描,比较当前的数字和前面的数字,如果发现不是递增顺序,比如扫描到 1 发现比 4 小,那么将 1 插到前面的正确位置处,记操作1 次,问一个序列要变成一个递增的顺序需要操作几次 ?(前面的例子需要操作 1 次;而 4 3 2 1 需要操作 3 次!)

题目分析

C 题其实最简单,这里不需要排序,me 们只需要记住前面的最大的数字 max,如果被扫描的数字 d 比它 max 大,那么更新 max 的值,而操作次数不用 +1;如果 d 比 max 小,那么操作次数 +1,然后直接扫描下一个。完全是顺序扫描一遍就可以 okay 的题目。

B 题是个物理题目,所以需要动手演算一下计算公式。小球在水平方向上作匀速直线运动,在竖直方向上作上抛或是说自由落体运动,所以:

vcosθ⋅t = D 
    2vsinθ = g⋅t
 ∴ sin(2θ) = gD/v2

所以,这个题目实际上只要根据公式计算即可。(不过 c/c++ 库的 asin 求出的结果是弧度,所以还需要转换为角度 :π = 180° )

A 题貌似才是不好解决的问题。me 最初想:要划分成两组,当然根据第一对冤家就可以分成两组,比如 a b,a 是一组,b 是在一组,后米遇到 a c 的情况那么 b c 就是同一组。不过想想如果遇到 d f 的情况呢?猜测 d 和 a 一组,后来可能发现不对;然后再猜测 d 和 b 一组?这样的话,再遇到 g 和 h 情形,然后再两次猜测 ? 最初认为划分成两组完全不需要用到“并查集”的结构,不过后来还是使用并查集解决了。me 以前碰到过一个“朋友的朋友还是朋友,敌人的敌人也是朋友”这个题目,后来基本就是在原来的程序上修改了一下 AC 掉这道题目了。

A 题答题思路:首先保存所有这样的冤家对,然后遍历所有这样的对,比如 a b;查找所有和 a 有冤家关系的,那么和 b 并在一起;再查找和 b 有冤家关系的,和 a 并在一起;处理的结果就是这些人尽可能滴合并在了一起(合并在一起的必须分配在同一组),最后重新扫描冤家关系,如果发现有两个竟然分到了同一组那么 No,如果没有那么就是 Yes !

如果按照上面的思路处理,实际上会得到很多组,然后对这些组其实可以合并成两组;不过因为题目不需要,所以 me 们也没有保存多余的信息然后最后合并。

A题:

#include <iostream>
#include <cstring>
#include <map>
using namespace std;
 
const int MAX = 105;
 
int parent[MAX];
int enemy[MAX][MAX];
 
int find_set(int node)
{
      int p = parent[node];
      while(p != 0){
          node = p;
          p = parent[p];
      }
      return node;
}
 
void union_set(int pa, int pb)
{
    parent[pb] = pa;
}
 
void friends(int a, int b)
{
    int pa = find_set(a);
    int pb = find_set(b);
    if(pa != pb)
        union_set(pa, pb);
}
 
int main()
{
    int i, j, k, n, r;
    string a, b;
    map<string, int> table;
    bool ok;
    int ra, rb;
    int value = 0;
   
    cin >> r;
    r = 1;
   
    while(cin >> n){
        memset(parent, 0, sizeof(parent));
        memset(enemy, 0, sizeof(enemy));
       
        for(i=0; i<n; ++i){
            cin >> a >> b;
            if(table[a] == 0)
                table[a] = ++value;
            if(table[b] == 0)
                table[b] = ++value;
            enemy[table[a]][table[b]] = enemy[table[b]][table[a]] = 1;
        }
        n = table.size();
        for(i=1; i<=n; ++i)
            for(j=1; j<=n; ++j){
                if(!enemy[i][j])
                    continue;
                for(k=1; k<=n; ++k)
                    if(enemy[i][k] == 1 && k!=j)    // line i
                        friends(j, k);
                for(k=1; k<=n; ++k)
                    if(enemy[k][j] == 1 && k!=i)    // column j
                        friends(i, k);
            }
        ok = true;
        for(i=1; i<=n && ok; ++i)
            for(j=1; j<=n && ok; ++j){
                if(enemy[i][j] == 0)
                    continue;
                ra = find_set(i);
                rb = find_set(j);
                if(ra == rb){
                    ok = false;
                }
            }
        cout << "Case #" << r << ": "  << (ok?"Yes":"No") << '\n';
        ++r;
    }
   
    return 0;
}
B题:

#include <stdio.h>
#include <math.h>
 
int main()
{
 
    int n;
    int v, d;
    double svalue, th, g=9.8, pi=3.141592653;
   
    scanf("%d", &n);
    n = 1;
   
    while(scanf("%d %d", &v, &d) != EOF){
        svalue = d*g/(v*v);
        th = asin(svalue)/pi*90;
        printf("Case #%d: %.7f\n", n, th);
        ++n;
    }
    return 0;
}

C题:

#include <stdio.h>
#include <string.h>
 
#define N 105
#define MAX 105
 
int main()
{
 
    int i, k, n, count;
    char card[N][MAX], *max;
   
    scanf("%d", &k);
    k = 1;
   
    while(scanf("%d", &n) != EOF){
        count = 0;
        getchar();
        for(i=0; i<n; ++i)
            fgets(card[i], MAX, stdin);
           
        for(i=1, max=card[0]; i<n; ++i){
            if(strcmp(max, card[i]) > 0){
                ++count;
            }else{
                max = card[i];
            }
        }
       
        printf("Case #%d: %d\n", k, count);
        ++k;
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值