资格赛只要做出一道题便可以,因为LOL比赛的关系也只是草草的做了一下,发现微软出题还是很有趣的,所以来整理一下~~~~(>_<)~~~~
发现微软的面试题目,很侧重于先推导中间结论,简化算法复杂度的思路,这也是我很喜欢的,虽然我的数学很弱。⊙﹏⊙b
//--------------------------------------------------------------------------------------格叽格叽------------------------------------------------------------------------------------------------------------------
Alice和Bob还有其他几位好朋友在一起玩传话游戏。这个游戏是这样进行的:首先,所有游戏者按顺序站成一排,Alice站第一位,Bob站最后一位。然后,Alice想一句话悄悄告诉第二位游戏者,第二位游戏者又悄悄地告诉第三位,第三位又告诉第四位……以此类推,直到倒数第二位告诉Bob。两位游戏者在传话中,不能让其他人听到,也不能使用肢体动作来解释。最后,Bob把他所听到的话告诉大家,Alice也把她原本所想的话告诉大家。
由于传话过程中可能出现一些偏差,游戏者越多,Bob最后听到的话就与Alice所想的越不同。Bob听到的话往往会变成一些很搞笑的东西,所以大家玩得乐此不疲。经过几轮游戏后,Alice注意到在两人传话中,有些词汇往往会错误地变成其他特定的词汇。Alice已经收集到了这样的一个词汇转化的列表,她想知道她的话传到Bob时会变成什么样子,请你写个程序来帮助她。
对于每组测试数据,单独输出一行“Case #c: s”。其中,c 为测试数据编号,s 为Bob所听到的句子。s 的格式与输入数据中Alice所想的句子格式相同。
#include <iostream> #include <map> #include <sstream> using namespace std; int T,C; int n,m; string tarstr; stringstream ss; string t,tt; map<string,string> varstr; int main() { cin>>T; C=0; while(T--){ C++; cin>>n>>m; varstr.clear(); for (int i=0;i<m;i++){ cin>>t>>tt; varstr[t]=tt; } cin.ignore(256,'\n'); getline(cin,tarstr); ss.clear(); ss<<tarstr; cout<<"Case #"<<C<<":"; while(ss>>tarstr){ for (int i=0;i<n-1;i++){ if (varstr.find(tarstr)==varstr.end()) break; tarstr=varstr[tarstr]; } cout<<" "<<tarstr; } cout<<endl; } }
在 N 条水平线与 M 条竖直线构成的网格中,放 K 枚石子,每个石子都只能放在网格的交叉点上。问在最优的摆放方式下,最多能找到多少四边平行于坐标轴的长方形,它的四个角上都恰好放着一枚石子。
输入文件包含多组测试数据。
第一行,给出一个整数T,为数据组数。接下来依次给出每组测试数据。
每组数据为三个用空格隔开的整数 N,M,K。
对于每组测试数据,输出一行"Case #X: Y",其中X表示测试数据编号,Y表示最多能找到的符合条件的长方形数量。所有数据按读入顺序从1开始编号。
#include <iostream> #include <map> #include <sstream> #include <math.h> using namespace std; int T,C; long n,m,k,ans,t,nt,mt,kt,addm,addn; long max(long a,long b){ if (a<b) return b; else return a; } int main() { cin>>T; for (C=1;C<=T;C++){ cin>>n>>m>>k; if (n<m) { t=n; n=m; m=t; } ans=0; for (nt=1;nt<=n;nt++){ t=0; mt=k / nt; if ((mt<=m) && (0<mt)){ t+=(mt-1)*(nt-1)*mt*nt>>2; kt=k-nt*mt; addm=0; addn=0; if (0<kt){ if ((kt<=mt) && (nt+1<=n)) addn=nt*kt*(kt-1)>>1; if ((kt<=nt) && (mt+1<=m)) addm=mt*kt*(kt-1)>>1; t+=max(addn,addm); } } ans = max(ans,t); } cout<<"Case #"<<C<<": "<<ans<<endl; } }
int calc(int x, int y){ int a = x, b = x, res = 2, c; while(b <= y){c = b; b = a + b; a = c; res++; } return res; }其他路径很短的情况,需要排序来判断。
//第三题来自mochavic #include <stdio.h> #include <vector> #include <algorithm> using namespace std; int deep[100010], f[100010][2]; vector<int> e[100010]; int c[60], cn; void dfs(int fa, int x, int d){ int i, y; deep[x] = d; for (i = 0; i < (int)e[x].size(); i += 2){ y = e[x][i]; if (y == fa) continue; f[y][0] = x; f[y][1] = e[x][i + 1]; dfs(x, y, d + 1); } } void pd(int x, int y){ while (deep[x] > deep[y]){ c[cn++] = f[x][1]; x = f[x][0]; if (cn == 50) return; } while (deep[y] > deep[x]){ c[cn++] = f[y][1]; y = f[y][0]; if (cn == 50) return; } while (x != y){ c[cn++] = f[x][1]; x = f[x][0]; c[cn++] = f[y][1]; y = f[y][0]; if (cn >= 50) return; } } int main(){ int T, ri = 1, n, m, x, y, z, i; scanf("%d", &T); while (T--){ scanf("%d", &n); for (i = 1; i <= n; i++) e[i].clear(); for (i = 1; i < n; i++){ scanf("%d%d%d", &x, &y, &z); e[x].push_back(y); e[x].push_back(z); e[y].push_back(x); e[y].push_back(z); } dfs(0, 1, 0); printf("Case #%d:\n", ri++); scanf("%d", &m); while (m--){ scanf("%d%d", &x, &y); cn = 0; pd(x, y); sort(c, c + cn); for (i = 0; i + 2 < cn; i++){ if (c[i] + c[i + 1] > c[i + 2]) break; } if (i + 2 < cn) printf("Yes\n"); else printf("No\n"); } } return 0; }