您的位置:首页 > 其它

uva 517 - Word(暴力+周期)

2014-01-27 23:56 288 查看
题目链接:uva 517 - Word

题目大意:给出一个字符串,以及8种变换方式,问说该字符串变换s次后的结果,注意字符串为环形,输出字典序最小的情况。

解题思路:因为字符串最长为15, 2^15<max(s), 所以一定会出现周期,暴力枚举周期。

#include <stdio.h>
#include <string.h>
#include <set>

using namespace std;

const int N = 20;

struct state {
int k, v;
friend bool operator < (const state& a, const state& b) {
return a.k < b.k;
}
};

int n, s, t[8];
set<state> rec;
char str
;

void init() {
rec.clear();
char cha
;

scanf("%s", str);
for (int i = 0; i < 8; i++) {
scanf("%s", cha);
int sum = 0;
for (int j = 0; j < 3; j++)
sum = cha[j] - 'a' + sum * 2;
t[sum] = cha[3] - 'a';
}
scanf("%d", &s);
}

int judge(char* a, char* b, int p, int& q) {
int sum;
for (int i = 0; i < n; i++) {
sum = (a[i] - 'a') * 4 + (a[(i+2)%n] - 'a') * 2 + a[(i+3)%n] - 'a';
b[(i+2)%n] = t[sum] + 'a';
}
b
= '\0';

sum = 0;
for (int i = 0; i < n; i++) sum = sum * 2 + b[i] - 'a';
state u;
u.k = sum; u.v = p;

set<state>::iterator it = rec.find(u);
if (it != rec.end()) {
q = it->v;
return p - q;
} else {
rec.insert(u);
return 0;
}
}

void solve() {
int cnt, q = 0;
bool flag = false;
char tmp
;
for (int i = 0; i < n; i++) q = q * 2 + str[i] - 'a';
state u; u.k = q; u.v = 0;
rec.insert(u);

for (int i = 1; i <= s; i++) {
cnt = judge(str, tmp, i, q);
if (cnt) {
cnt = (s-q) % cnt;
flag = true;
break;
}
strcpy(str, tmp);
}

if (flag) {
cnt += q;

for (set<state>::iterator i = rec.begin(); i != rec.end(); i++) {
if (i->v == cnt) {
cnt = i->k; break;
}
}

for (int i = n-1; i >= 0; i--) {
tmp[i] = 'a' + cnt % 2;
cnt /= 2;
}
}

char ans
;
strcpy(ans, tmp);
strcpy(str, tmp);

for (int i = 0; i < n; i++) {
tmp[0] = str[n-1];
strncpy(tmp+1, str, n-1);
if (strcmp(ans, tmp) > 0) strcpy(ans, tmp);
strcpy(str, tmp);
}
printf("%s\n", ans);
}

int main() {
while (scanf("%d%*c", &n) == 1) {
init();
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: