zoukankan      html  css  js  c++  java
  • 【codeforces 750C】New Year and Rating

    time limit per test2 seconds
    memory limit per test256 megabytes
    inputstandard input
    outputstandard output
    Every Codeforces user has rating, described with one integer, possibly negative or zero. Users are divided into two divisions. The first division is for users with rating 1900 or higher. Those with rating 1899 or lower belong to the second division. In every contest, according to one’s performance, his or her rating changes by some value, possibly negative or zero.

    Limak competed in n contests in the year 2016. He remembers that in the i-th contest he competed in the division di (i.e. he belonged to this division just before the start of this contest) and his rating changed by ci just after the contest. Note that negative ci denotes the loss of rating.

    What is the maximum possible rating Limak can have right now, after all n contests? If his rating may be arbitrarily big, print “Infinity”. If there is no scenario matching the given information, print “Impossible”.

    Input
    The first line of the input contains a single integer n (1 ≤ n ≤ 200 000).

    The i-th of next n lines contains two integers ci and di ( - 100 ≤ ci ≤ 100, 1 ≤ di ≤ 2), describing Limak’s rating change after the i-th contest and his division during the i-th contest contest.

    Output
    If Limak’s current rating can be arbitrarily big, print “Infinity” (without quotes). If the situation is impossible, print “Impossible” (without quotes). Otherwise print one integer, denoting the maximum possible value of Limak’s current rating, i.e. rating after the n contests.

    Examples
    input
    3
    -7 1
    5 2
    8 2
    output
    1907
    input
    2
    57 1
    22 2
    output
    Impossible
    input
    1
    -5 1
    output
    Infinity
    input
    4
    27 2
    13 1
    -50 1
    8 2
    output
    1897
    Note
    In the first sample, the following scenario matches all information Limak remembers and has maximum possible final rating:

    Limak has rating 1901 and belongs to the division 1 in the first contest. His rating decreases by 7.
    With rating 1894 Limak is in the division 2. His rating increases by 5.
    Limak has rating 1899 and is still in the division 2. In the last contest of the year he gets  + 8 and ends the year with rating 1907.
    In the second sample, it’s impossible that Limak is in the division 1, his rating increases by 57 and after that Limak is in the division 2 in the second contest.

    【题目链接】:http://codeforces.com/contest/750/problem/C

    【题解】

    我用的应该是最蠢的办法了;
    敲了180行.
    敲到一半我都快要哭出来了。
    但是痛苦是有回报的:)
    这次代码的注解写的很详细.可以到程序里面具体看;

    /*
        如果一直都没有出现div2
        那就说明全都在div1;
        则不管你怎么变都无所谓,都是无限大
        如果全都是div2他有一个上限1900
        (有可能从div2变成了div1,所以要特判一下)
        x=0
        然后对x进行ci的变换
        记录x的最大值
        如果max(x)>=0
        则rating为
            1899-(max(x)-x)
        如果max(x)<0
        则rating为
            1899+x
    
        有div1和div2夹杂
        找最后一个div1和div2的分割点
        i   c[i]   div2
        i+1 c[i+1] div1
        那就表示第i场比赛的时候
        rating<1900
        第i+1场比赛的时候rating>1900
        ci变化范围是1..100
        所以第i场的时候分数范围是
        1800..1899
        从大到小枚举
        ci不在这个范围输出无解
    
        i   c[i]   div1
        i+1 c[i+1] div2
        则第i场比赛的时候
        rating>=1900
        第i+1场比赛的时候rating<1900
        第i场比赛的时候rating的范围是1900..1999
        ci的话范围是-1..-100
        如果ci不在这个范围则也输出无解
        时间复杂度就是O(100*N)吧。不会超的.
    */


    【完整代码】

    #include <bits/stdc++.h>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define rei(x) scanf("%d",&x)
    #define rel(x) scanf("%I64d",&x)
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    const int MAXN = 2e5+100;
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    
    struct abc
    {
        int c,d;
    };
    
    int n,nd[3];
    abc a[MAXN];
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        rei(n);
        rep1(i,1,n)
        {
            rei(a[i].c);rei(a[i].d);
            nd[a[i].d]++;
        }
        if (nd[1]>0 && nd[2]==0)//都是div1
        {
            puts("Infinity");
            return 0;
        }
        if (nd[1]==0 && nd[2]>0)//都是div2
        {
            rep2(rating,1999,1900)//最后变成div1的情况
                {
                    int tempr = rating;
                    bool fi = true;
                    rep2(j,n,1)
                    {
                        tempr+=-a[j].c;
                        if (tempr>=1900)
                        {
                            fi = false;
                            break;
                        }
                    }
                    if (!fi)
                        continue;
                    if (fi)
                    {
                        printf("%d
    ",rating);
                        return 0;
                    }
                }
            int x = 0,ma = -2100000000,ans;//其他则都在div2
            rep1(i,1,n)
                {
                    x+=a[i].c;
                    ma = max(ma,x);
                }
            if (ma>=0)//最大值大于0那个时候到达最大1899
                ans = 1899-(ma-x);
            else//最大值小于0,则总是小于1899的
                ans = 1899+x;
            cout << ans << endl;
            return 0;
        }
        rep2(i,n,2)
            if (a[i].d!=a[i-1].d)
            {
                if (a[i-1].d==2 && a[i].d==1)//之前是div2涨分到div1
                {
                    rep2(rating,1899,1800)//从大到小枚举打i-1这场比赛之前的分数
                    {
                        bool fi = true;
                        int tempr = rating;
                        rep2(j,i-2,1)
                        {
                            tempr+=(-a[j].c);//看看减回去之后能不能打那场比赛
                            if (tempr>=1900 && a[j].d==2)
                            {
                                fi = false;
                                break;
                            }
                            if (tempr<1900 && a[j].d==1)
                            {
                                fi = false;
                                break;
                            }
                        }
                        if (!fi) continue;
                        tempr = rating;
                        rep1(j,i-1,n)//看看打完这场比赛之后是不是真的能打下一场比赛
                        {
                            tempr+=a[j].c;
                            if (tempr>=1900 && a[j+1].d==2)//判断依据是下一场比赛
                            {
                                fi = false;
                                break;
                            }
                            if (tempr<1900 && a[j+1].d==1)
                            {
                                fi = false;
                                break;
                            }
                        }
                        if (!fi) continue;
                        if (fi)
                        {
                            printf("%d
    ",tempr);
                            return 0;
                        }
                    }
                    puts("Impossible");
                    return 0;
                }
                else
                    if (a[i-1].d==1 && a[i].d==2)
                    {
                        rep2(rating,1999,1900)//打第i-1场比赛之前分数为1900.1999这个区间
                        {
                            bool fi = true;
                            int tempr = rating;
                            rep2(j,i-2,1)//看看倒回去是不是每场比赛都真的能打
                            {
                                tempr+=(-a[j].c);
                                if (tempr>=1900 && a[j].d==2)
                                {
                                    fi = false;
                                    break;
                                }
                                if (tempr<1900 && a[j].d==1)
                                {
                                    fi = false;
                                    break;
                                }
                            }
                            if (!fi) continue;
                            tempr = rating;
                            rep1(j,i-1,n)//继续往前打
                            {
                                tempr+=a[j].c;
                                if (tempr>=1900 && a[j+1].d==2)//看看下一场比赛能不能打
                                {
                                    fi = false;
                                    break;
                                }
                                if (tempr<1900 && a[j+1].d==1)
                                {
                                    fi = false;
                                    break;
                                }
                            }
                            if (!fi) continue;
                            if (fi)
                            {
                                printf("%d
    ",tempr);
                                return 0;
                            }
                        }
                        puts("Impossible");
                        return 0;
                    }
                break;
            }
        return 0;
    }
  • 相关阅读:
    Java http方式提交短信到短信网关
    表单提交set集合问题
    java 追加文件
    readonly和const 二者的区别
    自定义控件的实现
    sql 分页常见做法
    数据库通用连接类
    log4Net 使用
    NHibernate从入门到精通——第一个NHibernate应用程序
    自己写了一个js,但是最终不能控制住最后后的提交,前面的还是比较完美,大家看到后,能帮我解决一下吗?
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626746.html
Copyright © 2011-2022 走看看