Poj--1047 (字符串处理,KMP)
2014-05-29 00:35:26
题目链接:http://poj.org/problem?id=1047
题意 & 思路:判断给出的数num各乘以(1....n(num的位数))是否都是循环数。显然的大数乘法,我的思路是将原num扩展成两倍长(如1245扩展为12451245),再对每个积进行KMP匹配,全配上说明是循环数。
#include <cstdio> #include <string.h> #include <iostream> using namespace std; const int maxn = 60; char f[maxn + 5],tf[maxn + 5]; char arr[2 * maxn + 5]; int next[maxn + 5],tlen,len; void Get_next(){ next[0] = -1; int i = 0,j = -1; while(i != tlen - 1){ if(j == -1 || tf[i] == tf[j]){ ++i; ++j; next[i] = (tf[i] != tf[j] ? j : next[j]); } else{ j = next[j]; } } } bool KMP(){ Get_next(); int i = 0,j = 0; while(i != 2 * len && j != tlen ){ if(j == -1 || arr[i] == tf[j]){ ++i; ++j; } else{ j = next[j]; } } if(j == tlen ){ return true; } else{ return false; } } int main(){ while(scanf("%s",arr) == 1){ len = strlen(arr); for(int i = len; i < 2 * len; i++){ arr[i] = arr[i - len];//构造双倍字符数组 } arr[2 * len] = '\0'; for(int j = 0; j < maxn + 5; j++){ f[j] = '0'; } for(int i = 0; i < len; i++){ f[len - i - 1] = arr[i]; }//逆序存储数字,并标记每个位数 int flag = 1; for(int i = 2; i <= len; i++){ int c = 0; tlen = 0; for(int j = 0;; j++){ int s = (f[j] - '0') * i + c;//s计算单位做乘法后加上进位c tf[j] = (s % 10) + '0'; c = s / 10; ++tlen; if(j >= len - 1 && c == 0){ break; } } char temp; for(int j = 0; j < tlen / 2; j++){ temp = tf[j]; tf[j] = tf[tlen - 1 - j]; tf[tlen - 1 - j] = temp; } if(!KMP()){ flag = 0; break; } } for(int i = 0; i < len; i++){ printf("%c",arr[i]); } if(!flag){ printf(" is not cyclic\n"); } else{ printf(" is cyclic\n"); } } return 0; }