POJ3274-Gold Balanced Lineup
2011-07-30 21:47
190 查看
转载请注明出处:優YoUhttp://user.qzone.qq.com/289065406/blog/1309220772
大致题意:[/b]
[/b]
[/b]
解题思路:[/b]
经典题,不转化问题很难做,先根据官方的方法转化问题,把“求最远的两行间各个特征出现次数相等”转化为“求最远的相同两行”,再用Hash查找。
这是官方解题报告——
Considerthepartialsumsequenceofeachofthekfeaturesbuiltbytakingthe
sumofallthevaluesuptopositioni.Theproblemisequivalentto:
Givenanarrays
[k],findi,j,withthebiggestseparationforwhichs[i]
[l]-s[j][l]isconstantforalll.
Theproblemisnowtodothisefficiently.Noticethats[i][l]-s[j][l]being
constantforalllisequivalenttos[i][l]-s[j][l]=s[i][1]-s[j][1]forall
l,whichcanberearrangedtobecomes[i][l]-s[i][1]=s[j][l]-s[j][1]forall
l.Therefore,wecanconstructanotherarraya
[k]wherea[i][j]=s[i][j]-
s[i][1]andthegoalistofindiandjwiththebiggestseparationforwhich
a[i][l]=a[j][l]foralll.
Thiscanbedonebysortingallthea[i]entries,whichtakesO(nklogn)time
(althoughinpracticerarelywillallkelementsbecompared).Another
alternativeistogobyhashing,givinganO(nk)solution.Bothsolutionsare
fairlystraightforwardoncethefinalarrayisconstructed.
大概意思就是:
数组sum[i][j]表示从第1到第i头cow属性j的出现次数。
所以题目要求等价为:
求满足
sum[i][0]-sum[j][0]=sum[i][1]-sum[j][1]=.....=sum[i][k-1]-sum[j][k-1](j<i)
中最大的i-j
将上式变换可得到
sum[i][1]-sum[i][0]=sum[j][1]-sum[j][0]
sum[i][2]-sum[i][0]=sum[j][2]-sum[j][0]
......
sum[i][k-1]-sum[i][0]=sum[j][k-1]-sum[j][0]
令C[i][y]=sum[i][y]-sum[i][0](0<y<k)
初始条件C[0][0~k-1]=0
所以只需求满足C[i][]==C[j][]中最大的i-j,其中0<=j<i<=n。
C[i][]==C[j][]即二维数组C[][]第i行与第j行对应列的值相等,
那么原题就转化为求C数组中相等且相隔最远的两行的距离i-j[/b]。
以样例为例
先把7个十进制特征数转换为二进制,并逆序存放到特征数组feature[][],得到:
7à111
6à011
7à111
2à010
1à100
4à001
2à010
(行数为cow编号,自上而下从1开始;列数为特征编号,自左到右从0开始)
再求sum数组,逐行累加得,sum数组为
111
122
233
243
343
344
354
再利用C[i][y]=sum[i][y]-sum[i][0]求C数组,即所有列都减去第一列
注意C数组有第0行,为全0
000à第0行
000
011
011
021
010
011
021
显然第2行与第6行相等,均为011,且距离最远,距离为6-2=4,这就是所求。
但是最大数据有10W个,即10W行,因此不能直接枚举找最大距离,必须用Hash查找相同行,找到相同行再比较最大距离。
注意C数组的值可能为负数,因此生成key值时要注意保证key为非负数。
Source修正:
USACO2007MarchGold
http://www.cppblog.com/Felicia/archive/2007/12/29/39923.html
官方对Hint的解释:
INPUTDETAILS:
Thelinehas7cowswith3features;thetablebelowsummarizesthe
correspondence:
Feature3:1110010
Feature2:1111001
Feature1:1010100
Key:7672142
Cow#:1234567
OUTPUTFORMAT:
*Line1:Asingleintegergivingthesizeofthelargestcontiguous
balancedgroupofcows.
OUTPUTDETAILS:
Intherangefromcow#3tocow#6(ofsize4),eachfeatureappears
inexactly2cowsinthisrange:
Feature3:1001->twototal
Feature2:1100->twototal
Feature1:1010->twototal
Key:7214
Cow#:3456
*********************************************************************
SampleInput
73
7
6
7
2
1
4
2
73
7777777
44
1
2
4
8
44
8
1
2
4
54
3
1
2
4
8
15
3
12
3
13
7
65
16
8
4
2
31
SampleOutput
4
7
4
4
4
0
1
1
2
大致题意:[/b]
[/b]
[/b]
解题思路:[/b]
经典题,不转化问题很难做,先根据官方的方法转化问题,把“求最远的两行间各个特征出现次数相等”转化为“求最远的相同两行”,再用Hash查找。
这是官方解题报告——
Considerthepartialsumsequenceofeachofthekfeaturesbuiltbytakingthe
sumofallthevaluesuptopositioni.Theproblemisequivalentto:
Givenanarrays
[k],findi,j,withthebiggestseparationforwhichs[i]
[l]-s[j][l]isconstantforalll.
Theproblemisnowtodothisefficiently.Noticethats[i][l]-s[j][l]being
constantforalllisequivalenttos[i][l]-s[j][l]=s[i][1]-s[j][1]forall
l,whichcanberearrangedtobecomes[i][l]-s[i][1]=s[j][l]-s[j][1]forall
l.Therefore,wecanconstructanotherarraya
[k]wherea[i][j]=s[i][j]-
s[i][1]andthegoalistofindiandjwiththebiggestseparationforwhich
a[i][l]=a[j][l]foralll.
Thiscanbedonebysortingallthea[i]entries,whichtakesO(nklogn)time
(althoughinpracticerarelywillallkelementsbecompared).Another
alternativeistogobyhashing,givinganO(nk)solution.Bothsolutionsare
fairlystraightforwardoncethefinalarrayisconstructed.
大概意思就是:
数组sum[i][j]表示从第1到第i头cow属性j的出现次数。
所以题目要求等价为:
求满足
sum[i][0]-sum[j][0]=sum[i][1]-sum[j][1]=.....=sum[i][k-1]-sum[j][k-1](j<i)
中最大的i-j
将上式变换可得到
sum[i][1]-sum[i][0]=sum[j][1]-sum[j][0]
sum[i][2]-sum[i][0]=sum[j][2]-sum[j][0]
......
sum[i][k-1]-sum[i][0]=sum[j][k-1]-sum[j][0]
令C[i][y]=sum[i][y]-sum[i][0](0<y<k)
初始条件C[0][0~k-1]=0
所以只需求满足C[i][]==C[j][]中最大的i-j,其中0<=j<i<=n。
C[i][]==C[j][]即二维数组C[][]第i行与第j行对应列的值相等,
那么原题就转化为求C数组中相等且相隔最远的两行的距离i-j[/b]。
以样例为例
73
7
6
7
2
1
4
2
先把7个十进制特征数转换为二进制,并逆序存放到特征数组feature[][],得到:
7à111
6à011
7à111
2à010
1à100
4à001
2à010
(行数为cow编号,自上而下从1开始;列数为特征编号,自左到右从0开始)
再求sum数组,逐行累加得,sum数组为
111
122
233
243
343
344
354
再利用C[i][y]=sum[i][y]-sum[i][0]求C数组,即所有列都减去第一列
注意C数组有第0行,为全0
000à第0行
000
011
011
021
010
011
021
显然第2行与第6行相等,均为011,且距离最远,距离为6-2=4,这就是所求。
但是最大数据有10W个,即10W行,因此不能直接枚举找最大距离,必须用Hash查找相同行,找到相同行再比较最大距离。
注意C数组的值可能为负数,因此生成key值时要注意保证key为非负数。
Source修正:
USACO2007MarchGold
官方对Hint的解释:
INPUTDETAILS:
Thelinehas7cowswith3features;thetablebelowsummarizesthe
correspondence:
Feature3:1110010
Feature2:1111001
Feature1:1010100
Key:7672142
Cow#:1234567
OUTPUTFORMAT:
*Line1:Asingleintegergivingthesizeofthelargestcontiguous
balancedgroupofcows.
OUTPUTDETAILS:
Intherangefromcow#3tocow#6(ofsize4),eachfeatureappears
inexactly2cowsinthisrange:
Feature3:1001->twototal
Feature2:1100->twototal
Feature1:1010->twototal
Key:7214
Cow#:3456
*********************************************************************
//MemoryTime
//44152K1141MS
#include<iostream>
#include<cmath>
usingnamespacestd;
constintsize=100001;
constintmod=99991;
intfeature[size][30];//feature[i][j]标记第i只牛是否有特征j
intsum[size][30];//从第1到第i只牛,特征j总共出现了sum[i][j]次
intc[size][30];//c[i][j]=sum[i][j]-sum[i][0],即所有列都减去第一列后,值保存在c[][]
intN;//牛数量
intK;//特征数
intMaxLen;//最大距离
typedefclassHASH
{
public:
intpi;//保存c[i][j]的行地址c[i]的下标i
classHASH*next;
HASH()
{
next=0;
}
}HashTable;
HashTable*hash[mod];
/*检查c[ai][]与c[bi][]是否对应列相等*/
boolcmp(intai,intbi)
{
for(intj=0;j<K;j++)
if(c[ai][j]!=c[bi][j])
returnfalse;
returntrue;
}
voidHash(intci)
{
intkey=0;//生成关键字
for(intj=1;j<K;j++)
key+=c[ci][j]*j;
key=abs(key)%mod;//由于c[][]有正有负,因此key值可能为负数
if(!hash[key])//新key
{
HashTable*pn=newHashTable;
pn->pi=ci;
hash[key]=pn;
}
else//key值冲突
{
HashTable*pn=hash[key];
if(cmp(pn->pi,ci))
{
intdist=ci-(pn->pi);
if(MaxLen<dist)
MaxLen=dist;
return;//由于pi与ci对应列数字相等,且pi地址必定比ci小
}//而要求的是最大距离,因此不需要保存ci,判断距离后直接返回
else
{
while(pn->next)
{
if(cmp(pn->next->pi,ci))
{
intdist=ci-(pn->next->pi);
if(MaxLen<dist)
MaxLen=dist;
return;
}
pn=pn->next;
}
//地址冲突但c[][]各列的值不完全相同
HashTable*temp=newHashTable;
temp->pi=ci;
pn->next=temp;
}
}
return;
}
intmain(void)
{
freopen("in.txt","r",stdin);
while(cin>>N>>K)
{
/*Initial*/
for(intp=0;p<K;p++)
{
c[0][p]=0;//第0只牛的特征默认为全0
sum[0][p]=0;
}
memset(hash,0,sizeof(hash));
Hash(0);//把第0只牛先放入哈希表
MaxLen=0;
/*Input*/
for(inti=1;i<=N;i++)
{
intDexf;//十进制特征数
cin>>Dexf;
for(intj=0;j<K;j++)
{
feature[i][j]=Dexf%2;//Dexf转换为逆序二进制
Dexf/=2;
sum[i][j]=sum[i-1][j]+feature[i][j];
c[i][j]=sum[i][j]-sum[i][0];
}
Hash(i);
}
/*Output*/
cout<<MaxLen<<endl;
}
return0;
}
SampleInput
73
7
6
7
2
1
4
2
73
7777777
44
1
2
4
8
44
8
1
2
4
54
3
1
2
4
8
15
3
12
3
13
7
65
16
8
4
2
31
SampleOutput
4
7
4
4
4
0
1
1
2
相关文章推荐
- poj3274--Gold Balanced Lineup(hash)
- POJ3274-Gold Balanced Lineup
- POJ3274----Gold Balanced Lineup(黄金平衡)
- POJ3274《Gold Balanced Lineup》方法:哈希
- POJ3274 Gold Balanced Lineup
- poj3274 Gold Balanced Lineup
- POJ3274 -Gold Balanced Lineup- HASH+前缀和
- [POJ3274]-Gold Balanced Lineup
- [POJ3274] Gold Balanced Lineup
- [POJ3274 Gold Balanced Lineup]
- poj 3274 -- Gold Balanced Lineup
- POJ 3274 Gold Balanced Lineup 数组Hash
- poj 3274 Gold Balanced Lineup
- BZOJ1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列
- POJ Gold Balanced Lineup (哈希排序)
- bzoj 1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列——map+hash+转换
- POJ 刷题系列:3274. Gold Balanced Lineup
- POJ 3274 Gold Balanced Lineup
- poj 3274 Gold Balanced Lineup
- POJ 3274 Gold Balanced Lineup