Broken Necklace(USACO)

/* ID:tianlin2 PROG:beads LANG:C++ */ #include <iostream> #include <fstream> using namespace std; //若函数里要改变变量的值,需引用 bool eq(char &x,char &y) { if(x=='w'&&y=='b') return true; if(x=='b'&&y=='w') //注意函数里数据的变换 { y=x; return true; } if(x=='w'&&y=='r') return true; if(x=='r'&&y=='w') { y=x; return true; } if(x=='b'&&y=='b') return true; if(x=='w'&&y=='w') return true; if(x=='r'&&y=='r') return true; else return false; } int main() { ofstream fout("beads.out"); ifstream fin("beads.in"); int a,b=1,c=1; //b为每个位置能收集的珠子数目,c为能收集的最大珠子数目 fin>>a; char *q=new char[a+1]; for(int u=0;u!=a;++u) fin>>q[u]; for(int i=0;i!=a;++i) { //一个P字符数组副本,以免原始的q字符数组被改变 char *p=new char[a+1]; for(int t=0;t!=a;++t) p[t]=q[t]; b=1; int j=i; int o=i-1; if(o<0) o=a-1; //考虑到走一圈的情况,这里官方答案里一个函数处理得很好,我这里有点复杂了 while(j!=o) { int x=j+1; if(x==a) x=0; if(eq(p[j],p[x])) ++b; else break; ++j; if(j==a) j=0; } int h=i-1; if(h<0) h=a-1; //条件也是考虑到走一圈的情况(h!=j) if(h!=j) { b=b+1; while(h!=i) { int y=h-1; if(y<0) y=a-1; if(eq(p[h],p[y])) ++b; else break; --h; if(h<0) h=a-1; } } if(b>c) c=b; } delete []q; fout<<c<<endl; return 0; }

主要思路是,考虑珠子遇到珠子的几种情况:

当w遇到r或者w遇到b时,珠子颜色不变;

当r/b遇到w时,w变为r/b;

不能收集的情况则停止收集!

复杂度n的平方

 

官方答案(复杂度n,处理得很好):

#include <iostream> #include <fstream> #include <string> using namespace std; //复制珠子的一个副本,拼接到原来的珠子string后 int main() { fstream input, output; string inputFilename = "beads.in", outputFilename = "beads.out"; input.open(inputFilename.c_str(), ios::in); output.open(outputFilename.c_str(), ios::out); int n, max=0, current, state, i, j; string s; char c; input >> n >> s; //此处复制 s = s+s; for(i=0; i<n; i++) { c = (char) s[i]; //这里的state标记很重要 if(c == 'w') state = 0; else state = 1; j = i; current = 0; while(state <= 2) { // dont go further in second string than starting position in first string while(j<n+i && (s[j] == c || s[j] == 'w')) { current++; j++; } // while state++; c = s[j]; } // while if(current > max) max = current; } // for output << max << endl; return 0; } // main

 

 

你可能感兴趣的:(Broken Necklace(USACO))