这次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 = ;
for (int i = ; i < n; i++) {
cin >> a >> b >> c >> d;
ans += abs(c - a + ) * abs(d - b + );
}
cout << ans << endl;
return ;
}
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[];
long long t[];
int main() {
cin >> n;
t[] = ;
for (int i = ; i <= ; i++)
t[i] = t[i - ] * ;
f[] = ;
for (int i = ; i <= ; i++)
f[i] = f[i - ] + (t[i] - t[i - ]) * i + ;
long long ans;
long long base;
for (int i = ; i <= n; i++) {
if (t[i] > n) {
base = i - ;
break;
}
}
ans = f[base] + (n - t[base]) * (base + );
cout << ans << endl;
return ;
}
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 == ) {
cout << "YES" << endl;
return ;
}
while (m) {
int z = m % n;
if (z <= ) {
m /= n;
} else if (z == n - ) {
m = m / n + ;
} else {
cout << "NO" << endl;
return ;
}
}
cout << "YES" << endl;
return ;
}
D. Vanya and Triangles
给你二维坐标下的n个点,问一共能构成多少个面积不为0的三角形。
如果不考虑面积则总方案数为 c3n 。
如果有三点共线则这三点不能构成三角形。
我们枚举每一个点i,计算其他所有点与i连线的斜率,如果有重复的斜率则说明有三点共线,即,如果有m个点与i的连线斜率相同,则非法的方案数为 c2m 。
#include <bits/stdc++.h>
using namespace std;
const double INF = ;
const double eps = ;
struct Point{
int x, y;
Point() {}
Point(int a, int b) : x(a), y(b) {}
};
int n;
Point p[];
int main() {
cin >> n;
for (int i = ; i < n; i++)
cin >> p[i].x >> p[i].y;
if (n < ) {
cout << << endl;
return ;
}
long long tot = (long long)n * (n - ) * (n - ) / ;;
long long sum = ;
vector<double> ans;
for (int i = ; i < n; i++) {
ans.clear();
for (int j = i + ; j < n; j++) {
int dx = p[j].x - p[i].x;
int dy = p[j].y - p[i].y;
double k;
if (dx == ) k = INF;
else if (dy == ) k = ;
else k = (double)dy / (double)dx;
ans.push_back(k);
}
sort(ans.begin(), ans.end());
double num = ans[];
int cnt = ;
for (int j = ; j < ans.size(); j++) {
if (fabs(ans[j] - num) < eps) {
cnt++;
} else {
sum += (long long)cnt * ((long long)cnt - l) / ;;
cnt = ;
num = ans[j];
}
}
sum += (long long)cnt * ((long long)cnt - l) / ;
}
cout << tot - sum << endl;
return ;
}
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 = ; 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(-);
for (int i = ; i < n; i += )
if (str[i] == '*') pos.push_back(i);
pos.push_back(n);
int len = pos.size();
long long ans = ;
for (int i = ; i < len - ; i++) { // left
for (int j = i + ; j < len; j++) { // right
string s = str;
s.insert(pos[i] + , , '(');
s.insert(pos[j] + , , ')');
ans = max(ans, expression(s));
}
}
cout << ans << endl;
return ;
}