Hankerrank World CodeSprint #4 Gridland Provinces (字符串双hash )
2016-06-27 18:01
1556 查看
题目链接:https://www.hackerrank.com/contests/june-world-codesprint/challenges/gridland-provinces
题意:一个两行n列的字符格子,一个人必须走个哈密顿路径,任选起始和结束位置,最后求走出的字符串有多个不同的。
n<=1000
Observe that since the knight always completes his journey in minimum total time, he never visits the same city twice. In other words, the path formed by the Knight is a path.
Suppose the knight starts his journey from cell ,
visits every cell to its and
comes to cell ,
then visits cell and
every cell to its to
cell .
Now there are two possible options for the knight if he wishes to visit each cell .
He can move to
cell ,
visiting all cells in between, and then go up to cell .
From there visit all cells to its until
it reaches cell thereby
completing the tour.
Otherwise the knight can move to cell followed
by a move to cell .
In this case there are again two possible options for the knight. Move from cell to
cell followed
by a move to cell and
have two choices again. Or visit all cells to its ,
move and
visit all remaining cells to its .
Note that the knight can start from cell instead
of cell .
Also, the knight can start from column ,
visit every cell to its ,
move down/up and visit every cell to its until
it reaches column again
and repeat the same procedure with two choices as elaborated before. So we need to handle these cases as well with a similar strategy as described.
There are different
values for .
For each value of ,
the simulation described above can be done in .
The hash value of the final string can be calculated in after
some pre-processing. The number of possible
is then the number of found
overall which can be easily maintained with a hashset or a sorted array to remove duplicates. Overall complexity is with
a sorted array or , with
a hashset.
和官方题解思路一样,因为可以DP求出不同串的hash值,只需要O(1),所以一共有O(N* N)个串,最后std::unique()去重一下就好了。
吐槽一下,数据真强啊,单hash被卡了,双hash第一次 写,两个素数模数取的不好也会被卡,我取的1e9+7和1e9+9
题意:一个两行n列的字符格子,一个人必须走个哈密顿路径,任选起始和结束位置,最后求走出的字符串有多个不同的。
n<=1000
Observe that since the knight always completes his journey in minimum total time, he never visits the same city twice. In other words, the path formed by the Knight is a path.
Suppose the knight starts his journey from cell ,
visits every cell to its and
comes to cell ,
then visits cell and
every cell to its to
cell .
Now there are two possible options for the knight if he wishes to visit each cell .
He can move to
cell ,
visiting all cells in between, and then go up to cell .
From there visit all cells to its until
it reaches cell thereby
completing the tour.
Otherwise the knight can move to cell followed
by a move to cell .
In this case there are again two possible options for the knight. Move from cell to
cell followed
by a move to cell and
have two choices again. Or visit all cells to its ,
move and
visit all remaining cells to its .
Note that the knight can start from cell instead
of cell .
Also, the knight can start from column ,
visit every cell to its ,
move down/up and visit every cell to its until
it reaches column again
and repeat the same procedure with two choices as elaborated before. So we need to handle these cases as well with a similar strategy as described.
There are different
values for .
For each value of ,
the simulation described above can be done in .
The hash value of the final string can be calculated in after
some pre-processing. The number of possible
is then the number of found
overall which can be easily maintained with a hashset or a sorted array to remove duplicates. Overall complexity is with
a sorted array or , with
a hashset.
和官方题解思路一样,因为可以DP求出不同串的hash值,只需要O(1),所以一共有O(N* N)个串,最后std::unique()去重一下就好了。
吐槽一下,数据真强啊,单hash被卡了,双hash第一次 写,两个素数模数取的不好也会被卡,我取的1e9+7和1e9+9
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <iostream> #include <string> #include <cmath> #include <set> #include <map> using namespace std; #define REP(i, a, b) for (int i = (a), i##_end_ = (b); i < i##_end_; ++i) #define MP make_pair #define PB push_back #define SZ(x) (int((x).size())) #define ALL(x) (x).begin(), (x).end() #define X first #define Y second template<typename T> inline bool chkmin(T &a, const T &b) { return a > b ? a = b, 1 : 0; } template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; } typedef long long LL; typedef pair<LL, LL> pii; const int oo = 0x3f3f3f3f; const int N = 600 * 4 + 10; pii h ; int top; LL mp[N * N * 4]; int all; char s[2] ; const int MOD = 1e9 + 7; const int MOD2 = 1e9 + 9; const LL BASE = 26; pair<LL, LL> p ; int main() { p[0].X = 1; for(int i = 1; i <= N - 10; i ++) p[i].X = p[i - 1].X * BASE % MOD; p[0].Y = 1; for(int i = 1; i <= N - 10; i ++) p[i].Y = p[i - 1].Y * BASE % MOD2; int T; cin >> T; while(T --) { int n; cin >> n; scanf("%s", s[0] + 1); scanf("%s", s[1] + 1); all = 0; int now = 0; top = 0; for(int i = 1; i <= n; i ++, now ^= 1) { pii tmp = pii(0, 0), nhash = pii(0, 0); if(now) { tmp.X = (s[0][i - 1] * BASE + s[1][i - 1]) % MOD; tmp.Y = (s[0][i - 1] * BASE + s[1][i - 1]) % MOD2; for(int j = i - 1; j >= 1; j --) nhash.X = (nhash.X * BASE + s[0][j]) % MOD; for(int j = 1; j <= i - 1; j ++) nhash.X = (nhash.X * BASE + s[1][j]) % MOD; for(int j = i - 1; j >= 1; j --) nhash.Y = (nhash.Y * BASE + s[0][j]) % MOD2; for(int j = 1; j <= i - 1; j ++) nhash.Y = (nhash.Y * BASE + s[1][j]) % MOD2; } else { tmp.X = (s[1][i - 1] * BASE + s[0][i - 1]) % MOD; tmp.Y = (s[1][i - 1] * BASE + s[0][i - 1]) % MOD2; for(int j = i - 1; j >= 1; j --) nhash.X = (nhash.X * BASE + s[1][j]) % MOD; for(int j = 1; j <= i - 1; j ++) nhash.X = (nhash.X * BASE + s[0][j]) % MOD; for(int j = i - 1; j >= 1; j --) nhash.Y = (nhash.Y * BASE + s[1][j]) % MOD2; for(int j = 1; j <= i - 1; j ++) nhash.Y = (nhash.Y * BASE + s[0][j]) % MOD2; } for(int j = 1; j <= top; j ++) { h[j].X = (p[(i - 2) * 2].X * tmp.X + h[j].X) % MOD; h[j].Y = (p[(i - 2) * 2].Y * tmp.Y + h[j].Y) % MOD2; } h[++ top] = nhash; pii cur = pii(0, 0); if(now) { for(int j = i; j <= n; j ++) cur.X = (cur.X * BASE + s[1][j]) % MOD; for(int j = n; j >= i; j --) cur.X = (cur.X * BASE + s[0][j]) % MOD; for(int j = i; j <= n; j ++) cur.Y = (cur.Y * BASE + s[1][j]) % MOD2; for(int j = n; j >= i; j --) cur.Y = (cur.Y * BASE + s[0][j]) % MOD2; } else { for(int j = i; j <= n; j ++) cur.X = (cur.X * BASE + s[0][j]) % MOD; for(int j = n; j >= i; j --) cur.X = (cur.X * BASE + s[1][j]) % MOD; for(int j = i; j <= n; j ++) cur.Y = (cur.Y * BASE + s[0][j]) % MOD2; for(int j = n; j >= i; j --) cur.Y = (cur.Y * BASE + s[1][j]) % MOD2; } for(int j = 1; j <= top; j ++) { pii nowhash = pii( (p[(i - 1) * 2].X * cur.X + h[j].X) % MOD, (p[(i - 1) * 2].Y * cur.Y + h[j].Y) % MOD2); mp[++ all] = (nowhash.X << 32) | nowhash.Y; } } now = 1; top = 0; for(int i = 1; i <= n; i ++, now ^= 1) { pii tmp = pii(0, 0), nhash = pii(0, 0); if(now) { tmp.X = (s[0][i - 1] * BASE + s[1][i - 1]) % MOD; tmp.Y = (s[0][i - 1] * BASE + s[1][i - 1]) % MOD2; for(int j = i - 1; j >= 1; j --) nhash.X = (nhash.X * BASE + s[0][j]) % MOD; for(int j = 1; j <= i - 1; j ++) nhash.X = (nhash.X * BASE + s[1][j]) % MOD; for(int j = i - 1; j >= 1; j --) nhash.Y = (nhash.Y * BASE + s[0][j]) % MOD2; for(int j = 1; j <= i - 1; j ++) nhash.Y = (nhash.Y * BASE + s[1][j]) % MOD2; } else { tmp.X = (s[1][i - 1] * BASE + s[0][i - 1]) % MOD; tmp.Y = (s[1][i - 1] * BASE + s[0][i - 1]) % MOD2; for(int j = i - 1; j >= 1; j --) nhash.X = (nhash.X * BASE + s[1][j]) % MOD; for(int j = 1; j <= i - 1; j ++) nhash.X = (nhash.X * BASE + s[0][j]) % MOD; for(int j = i - 1; j >= 1; j --) nhash.Y = (nhash.Y * BASE + s[1][j]) % MOD2; for(int j = 1; j <= i - 1; j ++) nhash.Y = (nhash.Y * BASE + s[0][j]) % MOD2; } for(int j = 1; j <= top; j ++) { h[j].X = (p[(i - 2) * 2].X * tmp.X + h[j].X) % MOD; h[j].Y = (p[(i - 2) * 2].Y * tmp.Y + h[j].Y) % MOD2; } h[++ top] = nhash; pii cur = pii(0, 0); if(now) { for(int j = i; j <= n; j ++) cur.X = (cur.X * BASE + s[1][j]) % MOD; for(int j = n; j >= i; j --) cur.X = (cur.X * BASE + s[0][j]) % MOD; for(int j = i; j <= n; j ++) cur.Y = (cur.Y * BASE + s[1][j]) % MOD2; for(int j = n; j >= i; j --) cur.Y = (cur.Y * BASE + s[0][j]) % MOD2; } else { for(int j = i; j <= n; j ++) cur.X = (cur.X * BASE + s[0][j]) % MOD; for(int j = n; j >= i; j --) cur.X = (cur.X * BASE + s[1][j]) % MOD; for(int j = i; j <= n; j ++) cur.Y = (cur.Y * BASE + s[0][j]) % MOD2; for(int j = n; j >= i; j --) cur.Y = (cur.Y * BASE + s[1][j]) % MOD2; } for(int j = 1; j <= top; j ++) { pii nowhash = pii( (p[(i - 1) * 2].X * cur.X + h[j].X) % MOD, (p[(i - 1) * 2].Y * cur.Y + h[j].Y) % MOD2); mp[++ all] = (nowhash.X << 32) | nowhash.Y; } } for(int i = 1; i <= n / 2; i ++) swap(s[0][i], s[0][n - i + 1]), swap(s[1][i], s[1][n - i + 1]); now = 0; top = 0; for(int i = 1; i <= n; i ++, now ^= 1) { pii tmp = pii(0, 0), nhash = pii(0, 0); if(now) { tmp.X = (s[0][i - 1] * BASE + s[1][i - 1]) % MOD; tmp.Y = (s[0][i - 1] * BASE + s[1][i - 1]) % MOD2; for(int j = i - 1; j >= 1; j --) nhash.X = (nhash.X * BASE + s[0][j]) % MOD; for(int j = 1; j <= i - 1; j ++) nhash.X = (nhash.X * BASE + s[1][j]) % MOD; for(int j = i - 1; j >= 1; j --) nhash.Y = (nhash.Y * BASE + s[0][j]) % MOD2; for(int j = 1; j <= i - 1; j ++) nhash.Y = (nhash.Y * BASE + s[1][j]) % MOD2; } else { tmp.X = (s[1][i - 1] * BASE + s[0][i - 1]) % MOD; tmp.Y = (s[1][i - 1] * BASE + s[0][i - 1]) % MOD2; for(int j = i - 1; j >= 1; j --) nhash.X = (nhash.X * BASE + s[1][j]) % MOD; for(int j = 1; j <= i - 1; j ++) nhash.X = (nhash.X * BASE + s[0][j]) % MOD; for(int j = i - 1; j >= 1; j --) nhash.Y = (nhash.Y * BASE + s[1][j]) % MOD2; for(int j = 1; j <= i - 1; j ++) nhash.Y = (nhash.Y * BASE + s[0][j]) % MOD2; } for(int j = 1; j <= top; j ++) { h[j].X = (p[(i - 2) * 2].X * tmp.X + h[j].X) % MOD; h[j].Y = (p[(i - 2) * 2].Y * tmp.Y + h[j].Y) % MOD2; } h[++ top] = nhash; pii cur = pii(0, 0); if(now) { for(int j = i; j <= n; j ++) cur.X = (cur.X * BASE + s[1][j]) % MOD; for(int j = n; j >= i; j --) cur.X = (cur.X * BASE + s[0][j]) % MOD; for(int j = i; j <= n; j ++) cur.Y = (cur.Y * BASE + s[1][j]) % MOD2; for(int j = n; j >= i; j --) cur.Y = (cur.Y * BASE + s[0][j]) % MOD2; } else { for(int j = i; j <= n; j ++) cur.X = (cur.X * BASE + s[0][j]) % MOD; for(int j = n; j >= i; j --) cur.X = (cur.X * BASE + s[1][j]) % MOD; for(int j = i; j <= n; j ++) cur.Y = (cur.Y * BASE + s[0][j]) % MOD2; for(int j = n; j >= i; j --) cur.Y = (cur.Y * BASE + s[1][j]) % MOD2; } for(int j = 1; j <= top; j ++) { pii nowhash = pii( (p[(i - 1) * 2].X * cur.X + h[j].X) % MOD, (p[(i - 1) * 2].Y * cur.Y + h[j].Y) % MOD2); mp[++ all] = (nowhash.X << 32) | nowhash.Y; } } now = 1; top = 0; for(int i = 1; i <= n; i ++, now ^= 1) { pii tmp = pii(0, 0), nhash = pii(0, 0); if(now) { tmp.X = (s[0][i - 1] * BASE + s[1][i - 1]) % MOD; tmp.Y = (s[0][i - 1] * BASE + s[1][i - 1]) % MOD2; for(int j = i - 1; j >= 1; j --) nhash.X = (nhash.X * BASE + s[0][j]) % MOD; for(int j = 1; j <= i - 1; j ++) nhash.X = (nhash.X * BASE + s[1][j]) % MOD; for(int j = i - 1; j >= 1; j --) nhash.Y = (nhash.Y * BASE + s[0][j]) % MOD2; for(int j = 1; j <= i - 1; j ++) nhash.Y = (nhash.Y * BASE + s[1][j]) % MOD2; } else { tmp.X = (s[1][i - 1] * BASE + s[0][i - 1]) % MOD; tmp.Y = (s[1][i - 1] * BASE + s[0][i - 1]) % MOD2; for(int j = i - 1; j >= 1; j --) nhash.X = (nhash.X * BASE + s[1][j]) % MOD; for(int j = 1; j <= i - 1; j ++) nhash.X = (nhash.X * BASE + s[0][j]) % MOD; for(int j = i - 1; j >= 1; j --) nhash.Y = (nhash.Y * BASE + s[1][j]) % MOD2; for(int j = 1; j <= i - 1; j ++) nhash.Y = (nhash.Y * BASE + s[0][j]) % MOD2; } for(int j = 1; j <= top; j ++) { h[j].X = (p[(i - 2) * 2].X * tmp.X + h[j].X) % MOD; h[j].Y = (p[(i - 2) * 2].Y * tmp.Y + h[j].Y) % MOD2; } h[++ top] = nhash; pii cur = pii(0, 0); if(now) { for(int j = i; j <= n; j ++) cur.X = (cur.X * BASE + s[1][j]) % MOD; for(int j = n; j >= i; j --) cur.X = (cur.X * BASE + s[0][j]) % MOD; for(int j = i; j <= n; j ++) cur.Y = (cur.Y * BASE + s[1][j]) % MOD2; for(int j = n; j >= i; j --) cur.Y = (cur.Y * BASE + s[0][j]) % MOD2; } else { for(int j = i; j <= n; j ++) cur.X = (cur.X * BASE + s[0][j]) % MOD; for(int j = n; j >= i; j --) cur.X = (cur.X * BASE + s[1][j]) % MOD; for(int j = i; j <= n; j ++) cur.Y = (cur.Y * BASE + s[0][j]) % MOD2; for(int j = n; j >= i; j --) cur.Y = (cur.Y * BASE + s[1][j]) % MOD2; } for(int j = 1; j <= top; j ++) { pii nowhash = pii( (p[(i - 1) * 2].X * cur.X + h[j].X) % MOD, (p[(i - 1) * 2].Y * cur.Y + h[j].Y) % MOD2); mp[++ all] = (nowhash.X << 32) | nowhash.Y; } } sort(mp + 1, mp + 1 + all); int ans = unique(mp + 1, mp + 1 + all) - (mp + 1); printf("%d\n", ans); } }
相关文章推荐
- 资源网址
- RecyclerView瀑布流如何动态计算imageview的宽高
- python list常用操作
- leetcode 罗马数字与整数的转换算法
- 带宽计算
- Python3之configparser模块
- Python的GIL是什么鬼,多线程性能究竟如何
- WTL 如何获取OnMouseWheel 的鼠标信息
- 解决Mac外接显示器分辨率不正确问题
- javaweb学习总结(十六)——JSP指令
- CALayer 的简介 和Core Animation动画效果 A
- HoloLens开发手记 - Unity之Spatial Sounds 空间声音
- Spark的基本说明
- 【Objective-C】05-第一个OC的类
- 6410 内核的uboot-分析笔记
- Flask(11)-博客文章
- 关于IIS7.5下的web.config配置的一些问题
- i2c驱动程序
- DLL注入--设置消息钩子
- svn连接报错 Can't connect to host '*.*.*.*': 由于连接方在一段时间后没有正确答复或连接的主机没有响应,连接尝试失败。