How many---hdu2609(最小表示)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2609
给你n个01串,然后求这n个串中有几个不同的;
例如:1100 ,1001 ,0011 ,0110,这4个串都是相同的,因为他们可以通过移动得到;
我们可以通过最大最小表示法来求出串的最小字典序所对应的串,那么上面的四个串对应的都是0011,这样一来就可以很轻松的求出结果了;
后面的我们可以用把每次求得串插入到Trie树中,如果树中已经存在此串,那么就返回0,不存在就返回1;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<stdio.h> #include<string.h> #include<algorithm> #include<stdlib.h> using namespace std; const int N = 2e4+7; char s[N], s0[N]; struct node { node* next[2]; }; int Min_Index(char a[], int n) { int i=0, j=1, k=0; while(i<n && j<n && k<n) { int t = a[(i+k)%n] - a[(j+k)%n]; if(t == 0) k++; else { if(t < 0) j = j + k + 1; else i = i + k + 1; if(i == j) j++; k=0; } } return min(i, j); } int Tire(char a[], node* head) { int flag = 0; node *p = head; for(int i=0; a[i]; i++) { int k = a[i]-'0'; if(p->next[k]==NULL) { flag = 1;///建立字典树,如果a已经存在返回0,否则返回1,加到结果中去; p->next[k] = new node(); } p = p->next[k]; } return flag; } void FreeTire(node *head)///没有用到,但是还是留着当个知识点吧,释放内存; { node *p = head; for(int i=0; i<2; i++) { if(p->next[i] != NULL) FreeTire(p->next[i]); } free(p); } int main() { int n, ans, len, Min; node*head; while(scanf("%d", &n)!=EOF) { head = new node(); ans = 0; for(int i=1; i<=n; i++) { scanf("%s", s0); len = strlen(s0); strcpy(s, s0); strcat(s, s0); Min = Min_Index(s, len); memset(s0, 0, sizeof(s0)); strncpy(s0, s+Min, len); ans+=Tire(s0, head); } printf("%d\n", ans); /// FreeTire(head); } return 0; }
不用字典树:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<stdio.h> #include<string.h> #include<algorithm> #include<stdlib.h> using namespace std; const int N = 110; char s[N], s0[N], ss[N*N][N]; int Min_Index(char a[], int n) { int i=0, j=1, k=0; while(i<n && j<n && k<n) { int t = a[(i+k)%n] - a[(j+k)%n]; if(t == 0) k++; else { if(t < 0) j = j + k + 1; else i = i + k + 1; if(i == j) j++; k=0; } } return min(i, j); } int cmp(const void *p1, const void *p2) { return strcmp((char *)p1, (char *)p2); } int main() { int n, ans, len, Min, k; while(scanf("%d", &n)!=EOF) { if(n==0) { printf("0\n"); continue; } k = 0; for(int i=1; i<=n; i++) { scanf("%s", s0); len = strlen(s0); strcpy(s, s0); strcat(s, s0); Min = Min_Index(s, len); memset(s0, 0, sizeof(s0)); strncpy(s0, s+Min, len); s0[len] = '\0'; strcpy(ss[k], s0); k++; } qsort(ss, k, sizeof(ss[0]), cmp); ans = 1; for(int i=1; i<k; i++) { if(strcmp(ss[i], ss[i-1])!=0) ans++; } printf("%d\n", ans); } return 0; }