google亚太在线笔试2017-RoundB
来源:互联网 发布:ubuntu rc.local不存在 编辑:程序博客网 时间:2024/05/01 16:41
google亚太在线笔试2017-RoundB
Problem A
题意:
定义’(‘和’)’所组成的平衡串为:
(1).空串,or
(2).(S),S为平衡串,or
(3).S1S2,其中S1和S2均为平衡串
接下来给你由L个’(‘和R个’)’,求解怎样排列,可以使所得的字符串有最多的非空平衡子串,输出此时的平衡子串的数目
数据量:
0≤L≤105.
0≤R≤105.
1≤L+R≤105.
分析:
易证明:另n = min(L, R),可以得到的最多非空平衡子串数目为n*(n+1)/2;即排列成()()()….这样的形式
代码:
//#include <iostream>#include <fstream>using namespace std;#define mini(a, b) ((a)<(b)?(a):(b))long long T, L, R;ifstream cin("A-large.in", ios::in);ofstream cout("A-large.out", ios::out);int main(){ cin>>T; int Case = 0; while(T--){ Case ++; cin>>L>>R; long long num = mini(L, R); long long maximum = (num+1)*(num)/2; cout<<"Case #"<<Case<<": "<<maximum<<endl; } return 0;}
Problem B: Sherlock and Watson Gym Secrets
题意:
给定A, B, N, K,求存在多少对的(i, j)(其中1<=i, j<=N且i != j),使得K|
(iA+jB) ,输出mod109+7 的结果
数据量:
0≤A≤106.
0≤B≤106.
1≤K≤100000.
1≤N≤1018.
分析:
(iA+jB)modK=(iAmodK+jBmodK)
通过这个可以将N缩小到K的范围
剩下只需要考虑的是i != j这个条件,将其减去就可以
代码:
//#include <iostream>#include <fstream>using namespace std;#define mod 1000000007long long T, A, B, N, K;long long a[100000], b[100000];ifstream cin("B-large-practice.in", ios::in);ofstream cout("B-large-practice.out", ios::out);long long power(long long a, long long x){ long long res = 1; for(long long k = (1<<30);k >= 1;k >>= 1){ res = (res*res)%K; if((x&k) != 0) res = (res*a)%K; } return res;}int main(){ cin>>T; int Case = 0; while(T --){ Case ++; cin>>A>>B>>N>>K; long long num = 0, iA, jB; for(int i = 0;i < 100000;i ++){ a[i] = 0; b[i] = 0; } long long m = (N/K)%mod; long long n = N%K; for(int i = 1;i <= n;i ++){ iA = power(i, A); jB = power(i, B); if((iA + jB)%K == 0){ num = (num + ((m+1)*b[(K-iA)%K])%mod)%mod; num = (num + ((m+1)*a[(K-jB)%K])%mod)%mod; num = (num + ((m+1)*m)%mod)%mod; } else{ num = (num + ((m+1)*b[(K-iA)%K])%mod)%mod; num = (num + ((m+1)*a[(K-jB)%K])%mod)%mod; } a[iA] = (a[iA] + m + 1)%mod; b[jB] = (b[jB] + m + 1)%mod; } if(m > 0){ for(int i = n + 1;i <= K;i ++){ iA = power(i, A); jB = power(i, B); if((iA + jB)%K == 0){ num = (num + (m*b[(K-iA)%K])%mod)%mod; num = (num + (m*a[(K-jB)%K])%mod)%mod; num = (num + (m*(m-1))%mod)%mod; } else{ num = (num + (m*b[(K-iA)%K])%mod)%mod; num = (num + (m*a[(K-jB)%K])%mod)%mod; } a[iA] = (a[iA] + m)%mod; b[jB] = (b[jB] + m)%mod; } } cout<<"Case #"<<Case<<": "<<num<<endl; } return 0;}
Problem C: Watson and Intervals
题意:
定义区间[L, R]的面积如下:
R - L + 1,即区间所覆盖的整数数目
给你N个闭合区间,求删去哪个区间后,这N个区间所覆盖的面积之和最小,最小为多少(面积之和为所有区间所覆盖的不同整数的数目之和)
分析:
sweep line策略
代码:
#include <fstream>#include <algorithm>using namespace std;#define MIN(a,b) ((a)<(b)?(a):(b))#define MAX(a,b) ((a)>(b)?(a):(b))#define maxm 500000enum {INC, DEC};struct Interval{ int L; int R; int coverarea;}interval[maxm];struct Label{ int point; int sign; int covertime; bool operator < (const Label a) const{ return point < a.point; }}label[2*maxm];int cover[2*maxm];long long T, L1, R1, A, B, C1, C2, M, n;ifstream cin("C-large-practice.in", ios::in);ofstream cout("C-large-practice.out", ios::out);void init(){ interval[0].L = L1; interval[0].R = R1; for(int i = 1;i < n;i ++){ interval[i].L = (A*interval[i-1].L + B*interval[i-1].R + C1)%M; interval[i].R = (A*interval[i-1].R + B*interval[i-1].L + C2)%M; } long long x, y; for(int i = 0;i < n;i ++){ x = interval[i].L; y = interval[i].R; interval[i].L = MIN(x, y); interval[i].R = MAX(x, y); label[2*i].point = interval[i].L; label[2*i].sign = INC; label[2*i+1].point = interval[i].R + 1; label[2*i+1].sign = DEC; } sort(label, label + 2*n);}int binary_search(int begins, int ends, int key){ if(begins > ends) return begins; else{ int r = (begins + ends)/2; if(label[r].point == key) return r; else if(label[r].point < key) return binary_search(r + 1, ends, key); else return binary_search(begins, r - 1, key); }}int solve(){ int covertime = 0; for(int i = 0;i < 2*n;i ++){ if(label[i].sign == INC) covertime ++; else covertime --; label[i].covertime = covertime; } cover[0] = 0; for(int i = 1;i < 2*n;i ++){ cover[i] = cover[i-1]; if(label[i-1].covertime == 1) cover[i] += (label[i].point - label[i-1].point); } int labelL, labelR; for(int i = 0;i < n;i ++){ labelL = binary_search(0, 2*n-1, interval[i].L); labelR = binary_search(0, 2*n-1, interval[i].R + 1); interval[i].coverarea = cover[labelR] - cover[labelL]; } int max_coverarea = 0; for(int i = 0;i < n;i ++) if(interval[i].coverarea > max_coverarea) max_coverarea = interval[i].coverarea; int sum_coverarea = 0; for(int i = 0;i < 2*n-1;i ++) if(label[i].covertime > 0) sum_coverarea += (label[i+1].point - label[i].point); sum_coverarea -= max_coverarea; return sum_coverarea;}int main(){ cin>>T; int Case = 0; while(T --){ Case ++; cin>>n>>L1>>R1>>A>>B>>C1>>C2>>M; init(); cout<<"Case #"<<Case<<": "<<solve()<<endl; } return 0;}
0 0
- google亚太在线笔试2017-RoundB
- google 2014在线笔试题
- Google apac 在线笔试round2
- 2014 google (在线)测试笔试题解
- 2013年google 在线笔试第五题被虐记。。
- 【在线笔试题解题报告系列】Google APAC 2017 University Test Round A
- 【在线笔试题解题报告系列】Google APAC 2017 University Test Round B
- 【在线笔试题解题报告系列】Google APAC 2017 University Test Round E
- google要在线笔试----bad horse 二分图
- hiho--google在线技术笔试模 第一题
- 名企笔试:2016 Google 在线评测题(数据传输问题)
- 滴滴2017在线笔试有感
- google笔试
- Google笔试
- Google笔试
- google笔试
- google笔试
- [2017腾讯校招在线笔试题]
- 前端样式库
- EditText设置输入类型
- 接口
- 133.Longest Words-最长单词(容易题)
- 第十期 路由器调试之HelloWorld 《路由器就是开发板》
- google亚太在线笔试2017-RoundB
- 这是我的第一篇csdn博客,仅作测试使用
- 微信开发一笔记
- SharedPreferences
- ACdream1077-LCM Challenge
- VB.net组合框笔记
- Android Studio配置,加快编译速度
- php定时执行、取消定时的伪代码(低级版本)
- 迭代器的小用法