题目1::
http://poj.org/problem?id=2833大意::n个数,去掉最大的n1个和最小的n2个数,(n1+n2 < n),求剩下的平均值。
题解:节省内存开销,使用两个堆维护,用最小堆维护最大的n1个数,用最大堆维护最小的n2个数,插满时,只需比较两个堆的front,再决定是否插入
代码:


#include <stdio.h>
#include <string.h>

const int INF = 0x7fffffff;

template<typename _Type>
class MaxHeap


{
private:
_Type data[20];
int size;
int cur;
public:
MaxHeap(int _n):size(_n),cur(0)

{
memset(data,0,sizeof(data));
data[0] = INF;
}
~MaxHeap()

{

}
void clear()

{
memset(data,0,sizeof(data));
cur = 0;
data[0] = INF;
}

void push(_Type _value)

{
if(isFull())

{
return ;
}
cur ++;
int i;
for(i = cur; data[i/2] < _value;i/=2)

{
data[i] = data[i/2];
}
data[i] = _value;
}

void pop()

{
if(isEmpty())
return ;
int lastElement = data[cur];
data[cur] = 0;
--cur;
int child = 0;
int i = 0;
for(i = 1; i*2 <= cur; i = child)

{
child = i*2;
if(child != cur && data[child+1] > data[child])

{
++child;
}
if(lastElement < data[child])
data[i] = data[child];
else
break;
}
data[i] = lastElement;
}

int front()const

{
return data[1];
}

bool isFull()const

{
return cur >= size;
}
bool isEmpty()

{
return cur == 0;
}
};

template <typename _Type>
class MinHeap


{
private:
_Type data[20];
int size;
int cur;
public:
MinHeap(int _n):size(_n),cur(0)

{
memset(data,0,sizeof(data));
data[0] = -INF;
}
~MinHeap()

{
}
void clear()

{
memset(data,0,sizeof(data));
data[0] = -INF;
size = N;
cur = 0;
}

void push(_Type _value)

{
if(isFull())
return;
int i ;
cur++;
for(i = cur; data[i/2] > _value; i/= 2)

{
data[i] = data[i/2];
}
data[i] = _value;
}

void pop()

{
if(isEmpty())
return ;
int child = 0;
int i = 0;
int lastElement = data[cur];
data[cur] = 0;
--cur;
for(i = 1; i*2 <= cur; i = child)

{
child = i*2;
if(child != cur && data[child+1] < data[child])

{
child = child+1;
}
if(lastElement > data[child])
data[i] = data[child];
else
break;
}
data[i] = lastElement;
}

bool isFull()const

{
return cur >= size;
}

bool isEmpty()const

{
return cur == 0;
}

int front()const

{
return data[1];
}
};

int n,n1,n2;
void Test()


{
MinHeap<int> minHeap(n1);
MaxHeap<int> maxHeap(n2);
double sum = 0;
int tmp;
for(int i = 0; i < n; ++i)

{
scanf("%d",&tmp);
if(minHeap.isFull())

{
if(minHeap.front() < tmp)

{
minHeap.pop();
minHeap.push(tmp);
}
}
else

{
minHeap.push(tmp);
}
if(maxHeap.isFull())

{
if(maxHeap.front() > tmp)

{
maxHeap.pop();
maxHeap.push(tmp);
}
}
else

{
maxHeap.push(tmp);
}
sum += tmp;
}
while(!maxHeap.isEmpty())

{
sum -= maxHeap.front();
maxHeap.pop();
}
while(!minHeap.isEmpty())

{
sum -= minHeap.front();
minHeap.pop();
}

printf("%.6lf\n",sum/(n-n1-n2));
}

int main()


{
while(scanf("%d %d %d",&n1,&n2,&n) != EOF)

{
if(n1 == 0 && n2 == 0 && n == 0)
break;
Test();
}
return 0;
}

题目2:
http://poj.org/problem?id=3125题意:打印机取当前打印任务,若不是最高的打印任务,插到队尾,计算给定的任务在什么时候完成打印
题解:使用简单队列模拟,que[m] == 0表示完成了打印
代码:


#include <stdio.h>
#include <algorithm>
using namespace std;

int que[200];

void Test()


{
int n,m;
scanf("%d %d",&n,&m);
for(int i = 0; i < n; ++i)

{
scanf("%d",&(que[i]));
}
int time = 0;
int s = 0;
while(que[m] > 0)

{
if(que[s] > 0)

{
int maxP = -1;
for(int i = 0; i < n; ++i)

{
if(maxP < que[i])

{
maxP = que[i];
}
}
if(que[s] >= maxP)

{
++time;
que[s] = 0;
}
}
s = (s+1)%n;
}
printf("%d\n",time);
}

int main()


{
//freopen("data.txt","r",stdin);
int testcase;
scanf("%d",&testcase);
for(int i = 0; i < testcase; ++i)

{
Test();
}
return 0;
}

题目3:
http://poj.org/problem?id=2318题意:一个矩形,被n条直线划分,然后给定点(x,y),判断所在区域
题解:点与直线的关系,二分法
代码:


#include <stdio.h>
#include <string.h>

const int N = 5005;
int n,m,x1,y1,x2,y2;
int U[N];
int L[N];
int cnts[N];

void BinarySlove(int _x,int _y)


{
int low = -1;
int high = n;
int mid = 0;
while(low + 1< high)

{
mid = low + (high - low)/ 2;
double d = (double)(y1-y2)*(_x - U[mid]) + (double)(y1-_y)*(U[mid]-L[mid]);
if(d > 0)

{
low = mid ;
}
else

{
high = mid ;
}
}
cnts[high]++;
}

void Test()


{
memset(cnts,0,sizeof(cnts));
for(int i = 0; i < n; ++i)

{
scanf("%d %d",&U[i],&L[i]);
}
int xT,yT;
for(int i = 0; i < m; ++i)

{
scanf("%d %d",&xT,&yT);
BinarySlove(xT,yT);
}
for(int i = 0; i <= n; ++i)

{
printf("%d: %d\n",i,cnts[i]);
}
printf("\n");
}

int main()


{
//freopen("data.txt","r",stdin);
while(scanf("%d ",&n) != EOF)

{
if(n == 0)
break;
scanf("%d %d %d %d %d",&m,&x1,&y1,&x2,&y2);
Test();
}
return 0;
}

题目4:
http://poj.org/problem?id=2106题意:布尔表达式求解
题解:使用递归下降法LL求解
语法如下:
exp ---> (alt '|' )*alt
alt ---> (unit '&')*unit
unit ---> '('exp')' | '!'unit | 'F'|'V'
代码:


#include <stdio.h>
#include <string.h>

char context[256];
int cur;
int len;

bool exp(char* _context);

bool unit(char* _context)


{
if(_context[cur] == '!')

{
++cur;
return !unit(_context);
}
else if(_context[cur] == '(')

{
++cur;
bool ret = exp(_context);
++cur;
return ret;
}
else if(_context[cur] == 'F')

{
++cur;
return false;
}
else

{
++cur;
return true;
}
}

bool alt(char* _context)


{
bool ret = unit(_context);
while(cur < len && _context[cur] == '&')

{
++cur;
bool ret2 = unit(_context);
ret = ret && ret2;
}
return ret;
}

bool exp(char* _context)


{
bool ret = alt(_context);
while(cur < len && _context[cur] == '|')

{
++cur;
bool ret2 = alt(_context);
ret = ret || ret2;
}
return ret;
}

void Test()


{
len = strlen(context);
cur = 0;
bool ret = exp(context);
if(ret)
printf("V\n");
else
printf("F\n");
}

int main()


{
//freopen("data.txt","r",stdin);
char token;
int testcase = 0;
while(token = getchar(),token != EOF)

{
++testcase;
memset(context,0,sizeof(context));
int k = 0;
while(token != '\n' && token != EOF)

{
if(token !=' ')

{
context[k++] = token;
}
token = getchar();
}
if(strlen(context) > 0)

{
printf("Expression %d: ",testcase);
Test();
}
}
return 0;
}
posted on 2011-03-31 00:15
bennycen 阅读(1172)
评论(3) 编辑 收藏 引用 所属分类:
算法题解