| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
一个晚上还是AC,要是没有测试数据的话估计就过不了噢!!!还好。。。附我的方法,还没去看简单的方法,我的太长了。方法:我总假设处理当前行时,前面行之间的元素最大值都保存在队列里。。这样有了我当前行,那么加上前面我所处理过的值综合起来就能判断前一行的各个元素最大值等了,再同时更新队列!!实际上可以这么说,1.取一段区间,区间的第一个元素分开讨论,区间的最后一个元素分开讨论,区间中的元素可以和前面行的元素与之讨论!!
附代码::
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
using namespace std;
struct State
{
int num;
int v;
int Max;
int l,r;
State(){num=0;v=0;Max=-1;l=r=-1;}
};
#define N 30000
#define M 1505
State pre[M];
State Queue[N];
int ar[M][2];
int n;
int pairnum;
int statenum;
int front,rear;
int TT;
void InitQueue()
{
front = rear = 0;
}
bool Isempty()
{
if(front == rear) return true;
return false;
}
bool IsequalQueue(State b)
{
if(Isempty()) return false;
State tmp = Queue[front-1];
if(tmp.Max == b.Max && tmp.v == b.v && TT%n!=0) return true;
return false;
}
void InsertQueue(State b)
{
if(IsequalQueue(b))
{
Queue[front-1].num += b.num;Queue[front-1].r = b.r;
}
else {Queue[front++] = b;front %= N;}
}
State Getfront()
{
return Queue[rear];
}
void Pop()
{
rear++; rear %= N;
}
void Change(int a)
{
Queue[rear].num -= a;
Queue[rear].l = Queue[rear].v;
}
void Input()
{
pairnum = 0;
while(true)
{
int a,b;
scanf("%d%d",&a,&b);
if(a==0 && b==0) return ;
ar[pairnum][0] = a;
ar[pairnum++][1] = b;
}
}
bool IsequalState(State b)
{
if(statenum == 0) return false;
if(b.Max == pre[statenum-1].Max) return true;
return false;
}
//已经求出的状态压入
void InsertState(State b)
{
if(IsequalState(b)) pre[statenum-1].num += b.num;
else pre[statenum++] = b;
}
State GetEqualState(State &b,State &tmp)
{
State ha = Getfront();State tm=b;
if(ha.num < b.num )
{
tm.num = ha.num ;;tm.r = b.v;
tmp = ha;
b.l = b.v; b.num -= ha.num;
Pop();return tm;
}
if(ha.num == b.num )
{
tmp = ha;Pop();b.num = 0;
return tm;
}
if(ha.num > b.num )
{
tmp.l = ha.l; tmp.r = ha.v;tmp.Max = ha.Max ;tmp.num = b.num ;tmp.v = ha.v;
Change(b.num );
b.num = 0;
return tm;
}
}
int GetLLR(State a,int l)
{
if(l == 1) return a.l;
else
{
if(a.num == 1) return a.r;
else return a.v;
}
}
int GetRLR(State b,int l)
{
if(l != 1) return b.r;
else
{
if(b.num == 1) return b.l;
return b.v;
}
}
bool GetStatewhich(State &Q,State &b,State &x,State &y,int which)
{
if(which == 1)
{
if(b.num ==0) return false;
x = Q; y = b;
x.num = 1;x.l = GetLLR(Q,1);x.r = GetLLR(Q,2);
y.num = 1;y.l = GetLLR(b,1);y.r = GetLLR(b,2);
Q.num --;b.num --; Q.l = Q.v;
b.l = b.v;
return true;
}
if(which == 2)
{
if(b.num == 1 || b.num ==0) return false;
x = Q;y = b;
x.r = Q.v;y.r = b.v;x.num --;y.num --;
Q.l = GetRLR(Q,1);Q.num = 1;
b.l = GetRLR(b,1);b.num = 1;
return true;
}
if(which == 3)
{
if(b.num ==0) return false;
x = Q,y=b;Q.num =0;b.num = 0;return true;
}
}
void DealemptyQueue(State &b)
{
State s ;
s.Max = 0; s.num = b.num - b.num%n;TT += s.num ;
InsertState(s);
State var;
//var.l = var.v = var.r = b.v;
//var.Max = 0; var.num = n;
//InsertQueue(var);
b.num = b.num %n;
}
void DealState(State b)
{
while(b.num )
{
if(Getfront().num == n && (front - rear+N)%N == 1 && Getfront().v == b.v && Getfront().Max ==0 && b.num >=n)
DealemptyQueue(b);
State x,y;
x = GetEqualState(b,y);
State Q,B;
if(GetStatewhich(y,x,Q,B,1))
{
State s,var;
s.Max = max(Q.Max ,abs(Q.v-B.l));s.Max = max(s.Max,abs(Q.v-B.v));
s.Max = max(s.Max ,abs(Q.v - B.r));
s.num = 1; InsertState(s);
var.Max = max(abs(B.v-Q.l),abs(B.v-Q.v));
var.Max = max(var.Max ,abs(B.v-Q.r));
var.Max = max(var.Max ,abs(B.v - B.l));
var.Max = max(var.Max ,abs(B.v - B.r));
var.l = B.l;var.r = B.r;var.v = B.v;var.num = 1;
InsertQueue(var);TT++;
}
if(GetStatewhich(y,x,Q,B,2))
{
State s,var;
s.Max = max(abs(Q.v-B.v),Q.Max );s.num = B.num ;
InsertState(s);
var.Max = max(abs(Q.v-B.v),0);
var.num = B.num ;
var.l = var.v = var.r = B.v;
InsertQueue(var);TT+=B.num ;
}
if(GetStatewhich(y,x,Q,B,3))
{
State s,var;
s.Max = max(Q.Max ,abs(Q.v-B.l));s.Max = max(s.Max,abs(Q.v-B.v));
s.Max = max(s.Max ,abs(Q.v - B.r));
s.num = 1; InsertState(s);
var.Max = max(abs(B.v-Q.l),abs(B.v-Q.v));
var.Max = max(var.Max ,abs(B.v-Q.r));
var.Max = max(var.Max ,abs(B.v - B.l));
var.Max = max(var.Max ,abs(B.v - B.r));
var.l = B.l;var.r = B.r;var.v = B.v;var.num = 1;
InsertQueue(var);TT++;
}
}
}
void Solve()
{
if(pairnum == 1)
{
printf("%d\n",n);
printf("%d %d\n",0,ar[0][1]);
return ;
}
State s;
InitQueue();
int total = 0;
for(int i=0;i<pairnum;i++)
{
if(total %n == 0) s.l = ar[i][0];
else s.l = ar[i-1][0];
if(total + ar[i][1] >=n)s.r = ar[i][0];
else s.r = ar[i+1][0];
if(total + ar[i][1] >= n)
{
s.v = ar[i][0];s.num = n-total;
s.Max = 0;
InsertQueue(s);break;
}
else
{
s.v = ar[i][0];s.num = ar[i][1];
s.Max = 0;
total += s.num;
InsertQueue(s);
}
}
statenum = 0;
total = 0;
TT = 0;
for(int i=0;i<pairnum;i++)
{
s.num = ar[i][1];s.v = ar[i][0];
if(total%n==0) s.l = s.v;
else s.l = ar[i-1][0];
if((total + ar[i][1]) %n ==0) s.r = s.v;
else s.r= ar[i+1][0];
total += ar[i][1];
DealState(s);
}
while(!Isempty())
{
State s = Getfront();Pop();
InsertState(s);
}
total = 0;
int T = 0;
for(int i=0;i<statenum;i++)
if(total + pre[i].num >= n)
{ pre[i].num -= n-total;break;}
else {total += pre[i].num;pre[i].num = 0; }
printf("%d\n",n);
for(int i=0;i<statenum;i++)
if(pre[i].num !=0)
printf("%d %d\n",pre[i].Max ,pre[i].num );
}
int main()
{
//freopen("b.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(true)
{
scanf("%d",&n);
if(n==0){printf("0\n");break;}
Input();
Solve();
printf("0 0\n");
}
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator