您的位置:首页 > 其它

Broken Necklace(USACO)

2010-02-21 10:23 176 查看
/*
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: