google code jam
Kickstart Round H 2018
Problem A. Big Buttons
题意:构造一个只由“B”、“R”组成的长度为N的字符串,需要满足条件:不能出现输入的前缀。求有多少种字符串。
思路:只由“B”、“R”组成的长度为n的字符串共有2 ^ N种,减去含有禁止前缀的字符串即可。后者的计算,将字符串排序后,从最后一个字符串开始,向前找第一个它的前缀,如果找不到的话,将2 ^ len加到结果里。
代码:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<map>
#include<cmath>
#include<string>
#include<vector>
#include<set>
#include<queue>
#include<stack>
#include<iOStream>
#include<algorithm>
using namespace std;
#define debug(x) cout << #x << " = " << x << endl
#define lowbit(x) (x & (-x))
typedef long long LL;
typedef pair<int, int>PII;
const int maxn = 1e5 + 10;
const int inf = 0xfffffff;
const double pi = acos(-1);
string s[105], t[105];
int cnt = 0;
LL qwe (LL x,LL y){
LL t = 1;
while (y){
if (y%2!=0)
t = t * x;
y /= 2;
x = x * x;
}
return t;
}
bool check(string sp, string ss)
{
if(sp.length() > ss.length()) return false;
if(ss.substr(0, sp.length()) == sp) return true;
return false;
}
inline void open(string s){
freopen((s + ".in").c_str(), "r", stdin);
freopen((s + ".out").c_str(), "w", stdout);
}
int main()
{
open("A-large-practice");
int T, n, p;
scanf("%d", &T);
for(int cas = 1; cas <= T; cas++)
{
printf("Case #%d: ", cas);
scanf("%d%d", &n, &p);
for(int i = 1; i <= p; i++) cin >> s[i];
cnt = 0;
sort(s + 1, s + 1 + p);
LL sum = qwe(2, n);
for(int i = p; i >= 1; i--)
{
int flag = 0;
for(int j = i - 1; j >= 1; j--)
{
if(check(s[j], s[i]))
{
flag = 1;
break;
}
}
if(!flag) sum -= qwe(2, n - s[i].length());
}
printf("%lld\n", sum);
}
return 0;
}
Problem B. Mural
题意:一面墙由N个部分组成,每一部分有对应的美丽值,给一个部分涂刷后就能拥有这个部分的美丽值。每天早上可以涂刷一个部分,必须接着以前涂刷过的部分,晚上会有洪水毁坏一个在两边并且没有被涂刷的部分,求能保证的最大美丽值。
思路:维护一个长度为⌈n / 2⌉的子序列的最大和。
代码:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<map>
#include<cmath>
#include<string>
#include<vector>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
#include<algorithm>
using namespace std;
#define debug(x) cout << #x << " = " << x << endl
#define lowbit(x) (x & (-x))
typedef long long LL;
typedef pair<int, int>PII;
const int maxn = 5e6 + 10;
const int inf = 0xfffffff;
const double pi = acos(-1);
char s[maxn];
int a[maxn];
inline void open(string s){
freopen((s + ".in").c_str(), "r", stdin);
freopen((s + ".out").c_str(), "w", stdout);
}
int main()
{
open("B-large-practice");
int T, n;
scanf("%d", &T);
for(int cas = 1; cas <= T; cas++)
{
scanf("%d", &n);
scanf("%s", s + 1);
int len = n / 2;
if(n % 2) len++;
int l = 1, r = 0, sum = 0, Max = 0;
while(r <= n)
{
if(r - l + 1 < len)
{
r++;
sum += (s[r] - '0');
}
else
{
Max = max(Max, sum);
sum -= (s[l] - '0');
l++;
}
}
printf("Case #%d: %d\n", cas, Max);
}
return 0;
}
Problem C. Let Me Count The Ways
题意:2N个人,其中有m对新婚夫妻,他们一坐在一起就会给对方写爱情诗不划船(被我一jio踹下水!!),问有多少种安排方式使得没有一对新婚夫妻是坐在一起的。
思路:容斥的思想。
没有1对坐在一起的安排方式 = 总的安排方式 - 至少有一对夫妻坐在一起的安排方式
故计算公式为:
代码:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<map>
#include<cmath>
#include<string>
#include<vector>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
#include<algorithm>
using namespace std;
#define debug(x) cout << #x << " = " << x << endl
#define lowbit(x) (x & (-x))
typedef long long LL;
typedef pair<int, int>PII;
const int maxn = 2e5 + 10;
const int inf = 0xfffffff;
const int mod = 1e9 + 7;
const double pi = acos(-1);
inline void open(string s){
freopen((s + ".in").c_str(), "r", stdin);
freopen((s + ".out").c_str(), "w", stdout);
}
LL j[maxn + 5], nj[maxn + 5], g[maxn + 5], jc[maxn + 5];
LL poww(LL x, LL y)
{
LL ans = 1ll;
while(y > 0){
if(y & 1) ans = ans * x % mod;
y >>= 1;
x = x * x % mod;
}
return ans;
}
LL C(LL x, LL y){
if(x < y) return 0;
LL ans = 1ll;
ans = j[x] * nj[y] % mod * nj[x - y] % mod;
return ans;
}
void Init(){
j[1] = 1ll; j[0] = nj[0] = 1;
for(LL i = 2; i <= maxn; i++){
j[i] = j[i - 1] * i % mod;
}
nj[maxn] = poww(j[maxn], mod - 2) % mod;
for(LL i = maxn - 1; i >= 1; i--){
nj[i] = nj[i + 1] * (i + 1) % mod;
}
jc[0] = 1;
for(int i = 1; i < maxn; i++) jc[i] = ((jc[i - 1] * i) % mod);
}
int main()
{
open("C-large-practice");
Init();
int T, n, m;
scanf("%d", &T);
for(int cas = 1; cas <= T; cas++)
{
scanf("%d%d", &n, &m);
LL ans = 0;
for(int i = 0; i <= m; i++)
{
g[i] = ((((C(m, i) * jc[2 * n - i]) % mod) * poww(2, i)) % mod);
if(i % 2) ans = ((ans + mod - g[i]) % mod);
else ans = ((ans + g[i]) % mod);
}
printf("Case #%d: %lld\n", cas, ans);
}
return 0;
}
Kickstart Round G 2018
Problem A. Product triplets
题意:给出N个数,求至少满足以下三个条件中的一个的三元组(x, y, z)有多少个,其中1 <= x < y < z <= N。
- Ax = Ay × Az, and/or
- Ay = Ax × Az, and/or
- Az = Ax × Ay
思路:把数组排个序,枚举较小的两个数X和Y,二分查找在Y后面(包括值等于Y的数)值为X * Y的数有几个。
代码:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<map>
#include<cmath>
#include<string>
#include<vector>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
#include<algorithm>
using namespace std;
#define debug(x) cout << #x << " = " << x << endl
#define lowbit(x) (x & (-x))
typedef long long LL;
typedef pair<int, int>PII;
const int maxn = 1e5 + 10;
const int mod = 1e9 + 7;
const double pi = acos(-1);
LL a[maxn];
inline void open(string s)
{
freopen((s + ".in").c_str(), "r", stdin);
freopen((s + ".out").c_str(), "w", stdout);
}
int main()
{
open("A-large-practice");
int T, n;
scanf("%d", &T);
for(int cas = 1; cas <= T; cas++)
{
LL sum = 0;
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%lld", &a[i]);
sort(a + 1, a + 1 + n);
for(int i = 1; i <= n - 2; i++)
{
for(int j = i + 1; j <= n - 1; j++)
{
LL res = a[i] * a[j];
if(a[i] == 0 && a[j] == 0) sum += (n - j);
else
{
int pos1 = lower_bound(a + j + 1, a + n + 1, res) - a;
int pos2 = upper_bound(a + j + 1, a + n + 1, res) - a;
if(res == a[pos1]) sum += pos2 - pos1;
}
}
}
printf("Case #%d: %lld\n", cas, sum);
}
return 0;
}
相关阅读
1、OR 和 AND OR: 返回的结果是包含OR两边的任意关键词,比如: amazon OR ebay AND: 返回的结果是包含AND两边的关键词,比如: amazon
Google S2常用操作Google S2包引用经纬度 转 CellIdCellId 转 经纬度S2计算距离经纬度构建任意形状经纬度构建S2矩形经纬度构建S2
解决Google浏览器打不开网页 昨天电脑管家给我提示,您有7个危险漏洞,手残就点了一下。。。。结果。。浏览器访问的页面打不开了。
谈营销光谈战略战术不行,再牛逼的方案也需要依靠人去落实,才能得到更好的结果,如何找到更多优秀的人来合作也是我的日常思考范畴之一
离线地图服务主要帮助企业内部(局域网)环境搭建私有地图服务可应用在局域网地图发布,内网地图发布,手持设备地图发布,移动端地图发布,在