您的位置:首页 > 其它

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

#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);

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: