您的位置:首页 > 其它

csu 1008 - Horcrux

2012-04-14 10:23 295 查看
不得不表示,能用栈来做的题目前对我来说都很费解,这题又是抄的,来自校友JMDWQ,只不过把C改成了C++。开始时我用的是暴搜,数组的每一位就是一个“魂器”,而他的栈结构里每一位是连续相同的“魂器”的长度,明显要好的多。对他的核心代码,我的理解是这样的,大牛勿喷:

判断当前与前一位 相同:栈顶++;(当前连续区长度+1)

         不同:不能变化 || top==0:   s[++top] = 1;(开辟新区,长度为1)

             能变化 && top(存在区):只有一个区:栈顶++(长度+1);t = !t(最左边的区变了);

                          存在多个区:s[top-1] += s[top]+1;top--;(合并区);

现在举一个最后一种情况的例子:00110001,当前到最后一个,“1”,不同,可以变化,之前有三个区,s[1]==2,s[2]==2,s[3]==3,区3里的3个0都变为1,加上的当前的1(可以理解为区4),全都合并的区2里了,s[2] += s[3]+1;top--就是少一个区嘛。

最后不得不说代码中t的安排,真是巧妙。所有的区是0、1、0、1间隔的,t变化表示最左边的区变了,后来的top%2==t是用来判断当前也就是最后一个区是0还是1;本来我还是搞不清,后来看到t=f(第一个数),我觉悟了,原来t 一开始就是最左边的,它是0 t也是0,它是1 t也是1;然后它变t也变,完全一样嘛!t与top各2种情况,一共4种,枚举一下就发现这样会保证top指向0,真是妙,以后我也这样判断。

#include<iostream>
using namespace std;
const int MAXN = 100010;
unsigned short s[MAXN];
int main()
{
int t,f,top,ans,i,n,x;
while(cin>>n)
{
top = ans = 0;
memset(s,0,sizeof(s));
cin>>f;
t = f;
s[++top] = 1;
for(i = 1; i < n; i++)
{
cin>>x;
if(f!=x)
{
f = x;
if(i%2 && top)
if(top > 1)
s[top-1] += s[top]+1,top--;
else
s[top]++,t = !t;
else s[++top] = 1;
}
else s[top]++;
}
if(top%2 == t) top--;
while(top > 0)
{
ans += s[top];
top -= 2;
}
cout<<ans<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: