Codeforces Beta Round #97 (Div. 2)

Codeforces Beta Round #97 (Div. 2)

AB略,现在都忘了是啥题了。。

C 选择数组中的一个数,并把它改为另一个值(和原值不同),排序后求数组所有位置的最小可能值。 显然就是把最大的数改成1。注意特殊情况:数组里所有的数都是1。 当时把10^5的数组开成10^4了。。

D 判断给出的8个点能否构成一个矩形和一个正方形。 用next_permutation搞出排列,用两个向量数量积是否为零判断垂直,四个角都是直角,说明是矩形,四条边长度相等就是菱形,既是矩形又是菱形就是正方形。。


#include 
#include 
#include 
using namespace std;
const double eps = 1e-9;
struct TPoint
{
    int x, y;
}point[10];
int index[] = {0, 1, 2, 3, 4, 5, 6, 7};

inline int sgn(double x)
{
    return x>eps?1:x<-eps?-1:0;
}

//点积
int dot(const TPoint &a;, const TPoint &b;, const TPoint &c;)
{
    return (a.x - b.x) * (c.x - b.x) + (a.y - b.y) * (c.y - b.y);
}

//ab是否与cb垂直(b为交点)
bool isPerpendicular(const TPoint &a;, const TPoint &b;, const TPoint &c;)
{
    return !dot(a, b, c);
}

bool isRect(const TPoint &a;, const TPoint &b;, const TPoint &c;, const TPoint &d;)
{
    return isPerpendicular(a, b, c) && isPerpendicular(b, c, d) && isPerpendicular(c, d, a)
        && isPerpendicular(d, a, b);
}

inline int dis(const TPoint &a;, const TPoint &b;)
{
    return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}
bool isRhombus(const TPoint &a;, const TPoint &b;, const TPoint &c;, const TPoint &d;)
{
    return (dis(a, b) == dis(b, c)) && (dis(b, c) == dis(c, d)) && (dis(c, d) == dis(d, a));
}

bool isSquare(const TPoint &a;, const TPoint &b;, const TPoint &c;, const TPoint &d;)
{
    return isRect(a, b, c, d) && isRhombus(a, b, c, d);
}


int main()
{
    for (int i = 0; i < 8; i++) cin >> point[i].x >> point[i].y;
    do
    {
        if (isSquare(point[index[0]], point[index[1]], point[index[2]], point[index[3]]) &&
            isRect(point[index[4]], point[index[5]], point[index[6]], point[index[7]]))
        {
            printf("YES\n");
            for (int j = 0; j < 8; j++) index[j]++;
            printf("%d %d %d %d\n", index[0], index[1], index[2], index[3]);
            printf("%d %d %d %d\n", index[4], index[5], index[6], index[7]);
            return 0;
        }
    } while (next_permutation(index, index + 8));
    printf("NO\n");
    return 0;
}

E 这个题很不错。 输入数据由’0’, ‘1’, ‘?’组成。’?’可能是’0’或’1’。两人轮流取数字,直到最后只剩两个数字,先取的人希望最后剩下的数字最小,后取的人希望剩下的数字最大。 以下基本是官方题解的翻译…

先取的人显然会取最左面的1,后取的人显然会取最右面的0。 首先考虑没有问号的情况,设1有a个,0有b个,若a>=b+2,结果就是11;若a<=b-1,结果就是00。若a=b+1或a=b,结果可能是01或10,那么到底是哪种呢?因为每次都从左取0和1,而且最后剩下的两个数字里0和1都有,所以肯定没取到最右边的数字。那么如果最后一位是1,结果就是01,最后一位是0,结果就是10。

接下来考虑有问号的情况,设问号有c个。首先判断能不能出现00和11。判断a+c>=b+2和a<=b-1+c即可。然后考虑01和10,若最后一位不是问号,设问号中有x个是1,则c-x个是0。根据a+x=b+(c-x)+(a+b+c)%2,也就是以前的a=b+1或a=b,解出x的值,x必须大于等于零并小于等于c,根据最后一位的数字就能判断是否可能出现01和10。如果最后一位是问号,可以把它看成是0和1分别考虑,即–c后++a或++b,然后再判断x是否合法。


#include 
#include 
#include 
using namespace std;

int main()
{
    char ch[100005];
    int a = 0; // 1 count
    int b = 0; // 0 count
    int c = 0; // ? count
    int x = 0;
    int length;

    scanf("%s", ch);
    length = strlen(ch);

    for (int i = 0; i < length; i++)
    {
        switch (ch[i])
        {
            case '1':
                ++a;
                break;
            case '0':
                ++b;
                break;
            case '?':
                ++c;
                break;
        }
    }

    if (!c)
    {
        if (a < b) puts("00");
        if (a == b || a == b + 1)
        {
            if (ch[length - 1] == '1') puts("01");
            if (ch[length - 1] == '0') puts("10");
        }
        if (a > b + 1) puts("11");
    }
    else
    {
        if (a < b + c) puts("00");

        if (ch[length - 1] == '1')
        {
            x = (b + c - a + (a + b + c) % 2) / 2;
            if (x >= 0 && x <= c) puts("01");
        }
        if (ch[length - 1] == '0')
        {
            x = (b + c - a + (a + b + c) % 2) / 2;
            if (x >= 0 && x <= c) puts("10");
        }
        if (ch[length - 1] == '?')
        {
            --c;
            ++a;

            x = (b + c - a + (a + b + c) % 2) / 2;
            if (x >= 0 && x <= c) puts("01");

            --a;
            ++b;

            x = (b + c - a + (a + b + c) % 2) / 2;
            if (x >= 0 && x <= c) puts("10");

            --b;
            ++c;
        }

        if (a + c > b + 1) puts("11");
    }
    return 0;
}


comments powered by Disqus