11.2队内胡策

来源:互联网 发布:哪些域名不能备案 编辑:程序博客网 时间:2024/04/29 22:20

这次用的zhx的题目,zhx的题目还是一如既往的劲啊233。
t1数据有问题,看题面是可以拿栈搞一搞就过,但数据与题面不符,导致栈在不特判的情况下只能拿到30分,这里对t1就不多描述。


t2

【问题描述】

栈是一种强大的数据结构,它的一种特殊功能是对数组进行排序。例如,借
助一个栈,依次将数组 1,3,2 按顺序入栈或出栈,可对其从大到小排序:
1 入栈;3 入栈;3 出栈;2 入栈;2 出栈;1 出栈。
在上面这个例子中,出栈序列是 3,2,1,因此实现了对数组的排序。
遗憾的是,有些时候,仅仅借助一个栈,不能实现对数组的完全排序。例如
给定数组 2,1,3,借助一个栈,能获得的字典序最大的出栈序列是 3,1,2:
2 入栈;1 入栈;3 入栈;3 出栈;1 出栈;2 出栈。
请你借助一个栈,对一个给定的数组按照出栈顺序进行从大到小排序。当无
法完全排序时,请输出字典序最大的出栈序列。

【输入格式】

输入共2行。
第一行包含一个整数n,表示入栈序列长度。
第二行包含n个整数,表示入栈序列。输入数据保证给定的序列是1到 n 的全
排列,即不会出现重复数字。

【输出格式】

仅一行,共n个整数,表示你计算出的出栈序列。

【样例输入】

3
2 1 3

【样例输出】

3 1 2

【样例解释】

这回山里有座塔。

【数据规模与约定】

对于30%的数据,1 ≤n≤ 10^3。
对于60%的数据,1 ≤n≤ 10^5。
对于100%的数据,1 ≤n≤ 10^6。
一个比较简单的贪心,大体意思是用栈来保证一个数列的字典序最大,算法关键是在记录当前的最大值是否在栈里,在的话令最大值–,不在的话就把元素一直入栈直到当前的最大值入栈,具体见代码。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<stack>using namespace std;const int sz = 2000100;stack < int > s;int num[sz];bool use[sz];int n;int read(){    int x = 0 , f = 1;    char in = getchar();    while(in < '0' || in > '9')    {        if(in == '-')            f = -1;        in = getchar();    }    while('0' <= in && in <= '9')    {        x = (x << 3) + (x << 1) + in - '0';        in = getchar();    }    return x * f;}void start_work(){    n = read();    for(int i = 1 ; i <= n ; i ++)        num[i] = read();}int main(){    freopen("haha.in","r",stdin);    freopen("haha.out","w",stdout);    start_work();    int now = n;    for(int i = 1 ; i <= n ; i ++)    {        if(num[i] == now)        {            printf("%d ",num[i]);            now --;            while(use[now])                now --;            while(!s.empty() && now < s.top())            {                use[s.top()] = 0;                printf("%d ",s.top());                s.pop();            }        }        else            s.push(num[i]) , use[num[i]] = 1;    }    while(!s.empty())    {        printf("%d ",s.top());        s.pop();    }    fclose(stdin);    fclose(stdout);    return 0;}/*103 10 1 6 4 5 9 7 8 210 9 8 7 5 4 6 2 1 3*/

t3

【问题描述】

小 Q 对计算几何有着浓厚的兴趣。他经常对着平面直角坐标系发呆,思考
一些有趣的问题。今天,他想到了一个十分有意思的题目:
首先,小 Q 会在x轴正半轴和y轴正半轴分别挑选n个点。随后,他将x轴的
点与y轴的点一一连接,形成n条线段,并保证任意两条线段不相交。小 Q 确定这种连接方式有且仅有一种。最后,小 Q 会给出m个询问。对于每个询问,将会给定一个点P(Px, Py),请回答线段 OP 与n条线段会产生多少个交点?
小 Q 找到了正在钻研数据结构的你,希望你可以帮他解决这道难题。
【输入格式】
第1行包含一个正整数n,表示线段的数量;
第2行包含n个正整数,表示小 Q 在x轴选取的点的横坐标;
第3行包含n个正整数,表示小 Q 在y轴选取的点的纵坐标;
第 4 行包含一个正整数m,表示询问数量;
随后m行,每行包含两个正整数Px,Py,表示询问中给定的点的横、纵坐标。
【输出格式】
共m行,每行包含一个非负整数,表示你对这条询问给出的答案。
【样例输入】
3
4 5 3
3 5 4
2
1 1
3 3
【样例输出】
0
3
【样例解释】
然后塔里啥都没有。
【数据规模与约定】
对于50%的数据,1≤n,m,≤2x10^3。
对于100%的数据,1≤n,m≤2×10^5
,坐标范围≤ 10^8。
自学oi以来第一次在手动读入上翻车233,题目答案单调性显然,二分后验证就是小学数学了,这题数据挺良心的也不会卡精度。
代码如下

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define eps 1e-9using namespace std;const int sz = 400010;int n,m;int x_pos[sz];int y_pos[sz];double k[sz];double b[sz];int read(){    int x = 0 , f = 1;    char in = getchar();    while(in < '0' || in > '9')    {        if(in == '-')            f = -1;        in = getchar();    }    while('0' <= in && in <= '9')    {        x = (x << 3) + (x << 1) + in - '0';        in = getchar();    }    return x * f;}double calc_k(double x1,double y1,double x2,double y2){    return (y1 - y2) / (x1 - x2);}double calc_b(double x1,double y1,double x2,double y2){    double kk = (y1 - y2) / (x1 - x2);    return y1 - x1 * kk;}double calc_x(double k1,double b,double k2){    return b / (k2 - k1);}void start_work(){    n = read();    for(int i = 1 ; i <= n ; i ++)        x_pos[i] = read();    for(int i = 1 ; i <= n ; i ++)        y_pos[i] = read();    sort(x_pos+1,x_pos+n+1);    sort(y_pos+1,y_pos+n+1);    for(int i = 1 ; i <= n ; i ++)        k[i] = calc_k((double)x_pos[i],0.0,0.0,(double)y_pos[i]),        b[i] = calc_b((double)x_pos[i],0.0,0.0,(double)y_pos[i]);}bool check(int mid,double k2,double pos_x,double pos_y){    if(calc_x(k[mid],b[mid],k2) <= pos_x)        return true;    return false;}int EF(int pos_x,int pos_y){    double k2 = ((double)pos_y) / ((double)pos_x);    int l = 0 , r = n;    while(r - l > 1)    {        int mid = l + r >> 1;        if(check(mid,k2,(double)pos_x,(double)pos_y))            l = mid;        else            r = mid;    }    if(check(r,k2,(double)pos_x,(double)pos_y))        return r;    return l;}int main(){    freopen("hahaha.in","r",stdin);    freopen("hahaha.out","w",stdout);    start_work();    m = read();    for(int i = 1 ; i <= m ; i ++)    {        int x = read() , y =read();        printf("%d\n",EF(x,y));    }    fclose(stdin);    fclose(stdout);    return 0;}
0 0
原创粉丝点击