水题四道 3-30

水题四道 3-30
题目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;
}

你可能感兴趣的:(水题四道 3-30)