HDU 6136 模拟

2017-多校-8-1004 模拟


被模拟题搞翻了,搞了一下午,真TM傻逼

题目链接

思路:

  • 处理相对运动,最后一个肯定是最后的赢家,求出其他的相对速度和相对位置,将最后一个参赛者放到位置0
  • 处理可以从两个方向不被反方向行走参赛者干掉,能够到达原点的参赛者并标记出来
  • 然后处理同一个方向的能够最终到达原点的参赛者,比较这些参赛者,找出到达原点的最长时间。

调了无数遍的代码,终于A了

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <math.h>
#include <bitset>
#define CLS(x) memset(x, 0, sizeof(x))
using namespace std;
typedef pair<int,int> P;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-9;
const int N = 2e5 + 5;
const int mod = 1e9 + 7;
int L,n;
struct Node
{
    int x;
    int pow;
    int v;
};
bool cmp(Node a, Node b)
{
    return a.x < b.x;
}
Node node[N];
int t;
int rvis[N], lvis[N];
LL gcd(LL a, LL b)
{
    return b == 0 ? a : gcd(b, a%b);
}
int main()
{

    //freopen("1004.in","r",stdin);
    //freopen("1004.out","w",stdout);

    while(1 == scanf("%d", &t))
    {
        while(t--)
        {
            CLS(node);
            scanf("%d%d", &n,&L);
            for(int i = 1; i <= n; i++)
            {
                scanf("%d", &node[i].x);
                node[i].pow = i;
            }
            for(int i = 1; i <= n; i++)
                scanf("%d", &node[i].v);
            int sx,sp,sv;
            sx = node[n].x;
            sp = node[n].pow;
            sv = node[n].v;
            for(int i = 1; i <= n; i++)
            {
                node[i].v -= sv;
                node[i].x -= sx;
                if(node[i].x < 0) node[i].x += L;
            }
            sort(node + 1, node + 1 + n, cmp);
            CLS(lvis); CLS(rvis);
            int mxp = 0;
            for(int i = 2; i <= n; i++)
            {
                if(node[i].v > 0)
                    mxp = max(mxp, node[i].pow);
                else
                {
                    if(node[i].pow > mxp)
                    {
                        lvis[i] = 1;
                        mxp = 0;
                    }
                }
            }
            mxp = 0;
            for(int i = n; i >= 2; i--)
            {
                if(node[i].v < 0)
                    mxp = max(mxp, node[i].pow);
                else
                {
                    if(node[i].pow > mxp)
                    {
                        rvis[i] = 1;
                        mxp = 0;
                    }
                }
            }
            LL ansS = 0,ansV = 1, ansP = 0;
            stack<Node> s;
            LL ss = 0, vv = 1;
            for(int i = 2; i <= n; i++)
            {
                if(lvis[i])
                {
                    Node p = node[i];
                    p.v = -p.v;
                    int f = 0;
                    while(!s.empty() && (LL)s.top().x*p.v >= (LL)s.top().v*p.x)
                    {
                        if(s.top().pow < p.pow)
                            s.pop();
                        else
                        {
                            f = 1;
                            break;
                        }
                    }
                    if(!f)
                        s.push(p);
                }
            }
            while(!s.empty())
            {
                if((LL)s.top().x*(LL)vv > (LL)s.top().v*(LL)ss)
                {
                    ss = s.top().x;
                    vv = s.top().v;
                }
                s.pop();
            }
            ansS = ss;
            ansV = vv;
            ss = 0, vv = 1;
            for(int i = n; i >= 2; i--)
            {
                if(rvis[i])
                {
                    Node p = node[i];
                    p.x = L - p.x;
                    int f = 0;
                    while(!s.empty() && (LL)s.top().x*(LL)p.v >= (LL)s.top().v*(LL)p.x)
                    {
                        if(p.pow > s.top().pow)
                            s.pop();
                        else
                        {
                            f = 1;
                            break;
                        }
                    }
                    if(!f)
                        s.push(p);
                }
            }
            while(!s.empty())
            {
                if((LL)s.top().x*(LL)vv > (LL)s.top().v*(LL)ss)
                {
                    ss = s.top().x;
                    vv = s.top().v;
                }
                s.pop();
            }
            if(1LL*ss*ansV > 1LL*ansS*vv)
                ansS = ss, ansV = vv;
            LL g = gcd(ansS, ansV);
            printf("%lld/%lld\n", ansS/g, ansV/g);
        }
    }
    return 0;
}

错误原因:

  • 当时觉的正着搞有点麻烦,没想到用栈
  • 所以就反着找,比如考虑向左方向行进的参赛者,最后一个右边参赛者p往左边行进,如果左边的行进者p1武器比他垃圾,如果p1的速度小,会被p搞死,p1的速度大,那么p用的时间就比p1多了。如果p1的武器比p厉害,并且p1行进的比较慢,所以最后p会追上p1,然后被p1杀掉。所以更新方式就是只有遇到武器威力大,所用时间长的参赛者才会更新。
  • 但是,问题就是,p行进路上前面有两个参赛者,前面有一个跑的快的而且威力超级大,一个威力比p大,跑的慢,那个跑的快的会先把跑得慢的干掉。所以,就不能向上面的决策来处理了。

错误代码:

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <math.h>
#include <bitset>
#define CLS(x) memset(x, 0, sizeof(x))
using namespace std;
typedef pair<int,int> P;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-9;
const int N = 2e5 + 5;
const int mod = 1e9 + 7;
int L,n;
struct Node
{
    int x;
    int pow;
    int v;
};
bool cmp(Node a, Node b)
{
    return a.x < b.x;
}
Node node[N];
int t;
int rvis[N], lvis[N];
int S[N], V[N];
LL gcd(LL a, LL b)
{
    return b == 0 ? a : gcd(b, a%b);
}
int main()
{
    freopen("1004.in","r",stdin);
    freopen("10040.out","w",stdout);

    while(1 == scanf("%d", &t))
    {
        while(t--)
        {
            CLS(node);
            CLS(S);
            CLS(V);
            scanf("%d%d", &n,&L);
            for(int i = 1; i <= n; i++)
            {
                scanf("%d", &node[i].x);
                node[i].pow = i;
            }
            for(int i = 1; i <= n; i++)
                scanf("%d", &node[i].v);
            int sx,sp,sv;
            sx = node[n].x;
            sp = node[n].pow;
            sv = node[n].v;
            for(int i = 1; i <= n; i++)
            {
                node[i].v -= sv;
                node[i].x -= sx;
                if(node[i].x < 0) node[i].x += L;
            }
            sort(node + 1, node + 1 + n, cmp);
            for(int i = 2; i <= n; i++)
            {
                if(node[i].v > 0)
                {
                    S[i] = L-node[i].x;
                    V[i] = node[i].v;
                }
                else
                {
                    S[i] = node[i].x;
                    V[i] = -node[i].v;
                }
            }
            CLS(lvis);
            CLS(rvis);
            int mxp = 0;
            int cnt = 0;
            for(int i = 2; i <= n; i++)
            {
                if(node[i].v > 0)
                    mxp = max(mxp, node[i].pow);
                else
                {
                    if(node[i].pow > mxp)
                    {
                        lvis[i] = 1;
                        cnt++;
                        mxp = 0;
                    }
                }
            }
            cout<<cnt<<endl;
            mxp = 0;
            for(int i = n; i >= 2; i--)
            {
                if(node[i].v < 0)
                    mxp = max(mxp, node[i].pow);
                else
                {
                    if(node[i].pow > mxp)
                    {
                        rvis[i] = 1;
                        mxp = 0;
                    }
                }
            }
            int pos = -1;
            for(int i = n; i >= 2; i--)
            {
                if(lvis[i])
                {
                    pos = i;
                    break;
                }
            }
            printf("pos=%d ", pos);
            LL ansS = 0,ansV = 1, ansP = 0;
            int s2,v2;
            for(int i = n; i >= 2; i--)
            {
                if(lvis[i])
                {
                    if(node[i].pow > ansP && S[i]*ansV > V[i]*ansS)
                    {

                        ansS = S[i];
                        ansV = V[i];
                        ansP = node[i].pow;
                    }
                }
            }
            s2 = ansS;
            v2 = ansV;
            ansP = 0;
            ansS = 0;
            ansV = 1;
            for(int i = 2; i <= n; i++)
            {
                if(rvis[i])
                {
                    if(node[i].pow > ansP && S[i]*ansV > V[i]*ansS)
                    {
                        ansS = S[i];
                        ansV = V[i];
                        ansP = node[i].pow;
                    }

                }
            }
            if(1LL*(long long)s2*ansV > 1LL*(long long)ansS*v2)
                ansS = s2, ansV = v2;
            LL g = gcd(ansS, ansV);
            printf("%lld/%lld\n", ansS, ansV);
        }
    }
    return 0;
}
posted @ 2017-08-18 14:29  可达龙  阅读(256)  评论(0编辑  收藏  举报