Codeforces Round #308 (Div. 2)

这次cf真是发挥的有点醉,下次有div1我都不敢做了。

A. Vanya and Table

给你n个矩形,问你面积之和。

是面积之和不是面积并,直接算。然而我这个傻逼交错文件了WA了一发233333。

#include <bits/stdc++.h>

using namespace std;

int n;
int main() {
    int a, b, c, d;
    cin >> n;
    int ans = 0;
    for (int i = 0; i < n; i++) {
        cin >> a >> b >> c >> d;
        ans += abs(c - a + 1) * abs(d - b + 1);
    }
    cout << ans << endl;
    return 0;
}

B. Vanya and Books

给你一个整数n,问你从1到n一共有多少位。比如n = 13,1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13一共17位。

f[i]表示从1到 10i 一共有多少位,以753为例,从100到753都是3位数,所以答案就是f[2]+653*3。

#include <bits/stdc++.h>

using namespace std;

int n;
long long f[12];
long long t[12];
int main() {
    cin >> n;
    t[1] = 10;
    for (int i = 2; i <= 10; i++)
        t[i] = t[i - 1] * 10;
    f[1] = 11;
    for (int i = 2; i <= 10; i++)
        f[i] = f[i - 1] + (t[i] - t[i - 1]) * i + 1;
    long long ans;
    long long base;
    for (int i = 0; i <= n; i++) {
        if (t[i] > n) {
            base = i - 1;
            break;
        }
    }
    ans = f[base] + (n - t[base]) * (base + 1);
    cout << ans << endl;
    return 0;
}

C. Vanya and Scales

要用质量为 w0,w1,...,w100 的砝码各1个称出重量m,砝码可以放在天平左边也可以放在右边。问是否可以称出,输出YES或NO。

如样例3,7:左边放3和物品,右边放1和9即可。

假设可以称出,则用w进制表示m,每一位上一定是0,1或w - 1,否则一定不行。

而如果某一位是w - 1则说明当前砝码跟物品放在一起,相当于给物品加上了这个砝码的重量。

我们只需要模拟这个过程,提取m的每一位然后计算即可。

#include <bits/stdc++.h>

using namespace std;

int n, m;
int main() {
    cin >> n >> m;
    if (n == 3) {
        cout << "YES" << endl;
        return 0;
    }
    while (m) {
        int z = m % n;
        if (z <= 1) {
            m /= n;
        } else if (z == n - 1) {
            m = m / n + 1;
        } else {
            cout << "NO" << endl;
            return 0;
        }
    }
    cout << "YES" << endl;

    return 0;
}

D. Vanya and Triangles

给你二维坐标下的n个点,问一共能构成多少个面积不为0的三角形。

如果不考虑面积则总方案数为 c3n

如果有三点共线则这三点不能构成三角形。

我们枚举每一个点i,计算其他所有点与i连线的斜率,如果有重复的斜率则说明有三点共线,即,如果有m个点与i的连线斜率相同,则非法的方案数为 c2m

#include <bits/stdc++.h>

using namespace std;

const double INF = 1e10;
const double eps = 1e-8;

struct Point{
    int x, y;
    Point() {}
    Point(int a, int b) : x(a), y(b) {}
};

int n;
Point p[2005];

int main() {
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> p[i].x >> p[i].y;
    if (n < 3) {
        cout << 0 << endl;
        return 0;
    }
    long long tot = (long long)n * (n - 1) * (n - 2) / 6;;
    long long sum = 0;
    vector<double> ans;
    for (int i = 0; i < n; i++) {
        ans.clear();
        for (int j = i + 1; j < n; j++) {
            int dx = p[j].x - p[i].x;
            int dy = p[j].y - p[i].y;
            double k;
            if (dx == 0) k = INF;
            else if (dy == 0) k = 0.0;
            else k = (double)dy / (double)dx;
            ans.push_back(k);
        }
        sort(ans.begin(), ans.end());
        double num = ans[0];
        int cnt = 0;
        for (int j = 0; j < ans.size(); j++) {
            if (fabs(ans[j] - num) < eps) {
                cnt++;
            } else {
                sum += (long long)cnt * ((long long)cnt - 1ll) / 2;;
                cnt = 1;
                num = ans[j];
            }
        }
        sum += (long long)cnt * ((long long)cnt - 1ll) / 2;
    }
    cout << tot - sum << endl;
    return 0;
}

E. Vanya and Brackets

给你一个表达式,只有乘号和加号,数字都是1到9,要求加一个括号,使得表达式的值最大,问最大是多少。乘号个数<=15。

左括号一定在乘号右边,右括号一定在乘号左边,因为如果不是这样的话,一定可以调整括号的位置使表达式的值增大。这个应该不难想。

于是只要枚举括号的位置然后计算表达式即可。

#include <bits/stdc++.h>

using namespace std;

int n;
string str;
vector<int> pos;
stack<char> sc;
stack<long long> sn;

long long twoResult(long long a, long long b, char c) {
    return (c == '*') ? a * b : a + b;
}

void cal() {
    char t = sc.top();
    sc.pop();
    long long a = sn.top();
    sn.pop();
    long long b = sn.top();
    sn.pop();
    sn.push(twoResult(a, b, t));
}

long long expression(string s) {
    for (int i = 0; i < s.length(); i++) {
        char c = s[i];
        if (isdigit(c)) {
            sn.push(c - '0');
        } else if (c == '(') {
            sc.push(c);
        } else if (c == ')') {
            while (sc.top() != '(')
                cal();
            sc.pop();
        } else {
            if (c == '+') {
                while (!sc.empty() && sc.top() == '*')
                    cal();
                sc.push(c);
            } else sc.push(c);
        }
    }
    while (!sc.empty()) cal();
    return sn.top();
}

int main() {
    cin >> str;
    n = str.size();
    pos.push_back(-1);
    for (int i = 1; i < n; i += 2)
        if (str[i] == '*') pos.push_back(i);
    pos.push_back(n);
    int len = pos.size();
    long long ans = 0;
    for (int i = 0; i < len - 1; i++) { // left
        for (int j = i + 1; j < len; j++) { // right
            string s = str;
            s.insert(pos[i] + 1, 1, '(');
            s.insert(pos[j] + 1, 1, ')');
            ans = max(ans, expression(s));
        }
    }
    cout << ans << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值