ICPC 2019 Central Russia(9/11)
ICPC Central Russia Regional Contest (CRRC 19)
目录
A. Green tea
签到题
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
typedef long long LL;
int a, b;
int main() {
cin >> a >> b;
int res1, res2;
int minn = 0x3f3f3f3f;
for (int i = 0; i <= 1000; i++) {
for (int j = 0; j <= 1000; j++) {
if(i*a+j*b==80*(i+j)&&((i+j)!=0)){
if(i+j<minn){
res1 = i, res2 = j;
minn = i + j;
}
}
}
}
cout << res1 << ' ' << res2 << endl;
return 0;
}
B. Mysterious Resistors
大意:
给出k组串联的电阻,每组电阻都是\(r_i\)和R并联,现在给出k个\(r_i\),以及总电阻,求R
思路:
因为有单调性,所以直接二分去找即可
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int const MAXN = 2e5 + 10;
int n;
double m;
double r[MAXN];
bool check(double mid) {
double sum = 0;
for (int i = 1; i <= n; i++) {
sum += r[i] / (1.0 + r[i] / mid);
}
return sum > m;
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> r[i];
}
double l = 0, r = 1e5;
while (r - l > 1e-8) {
double mid = (l + r) / 2;
if (check(mid))
r = mid;
else
l = mid;
}
printf("%.8lf\n", l);
return 0;
}
C. Emoticons
大模拟。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int const MAXN = 2e5 + 10;
int n, m, T;
map<char, int> num;
unordered_map<char, string> mp;
vector<char> f;
int main() {
string s;
cin >> s;
mp['\\'] = ":-\\";
f.push_back('\\');
mp['P'] = ":-P";
f.push_back('P');
mp['D'] = ":D";
f.push_back('D');
mp['C'] = ":C";
f.push_back('C');
mp['8'] = "8-0";
f.push_back('8');
mp['E'] = ":-E";
f.push_back('E');
mp['%'] = "%0";
f.push_back('%');
mp['X'] = ":-X";
f.push_back('X');
mp['~'] = ":~(";
f.push_back('~');
mp['['] = "[:|||:]";
f.push_back('[');
mp['0'] = ":-0";
f.push_back('0');
mp['|'] = ":-|";
f.push_back('|');
for (int i = 0; i < s.size(); i++) {
num[s[i]]++;
// cout << s[i] << endl;
}
for (int v = 0; v < f.size(); v++) {
char fl = f[v];
if (num[fl]) {
string t = mp[fl];
int d = num[fl];
for (int i = 0; i < d; i++) {
// cout << fl << " " << t << endl;
cout << t << endl;
}
for (int i = 0; i < t.size(); i++) {
num[t[i]] -= d;
}
}
}
if (num[';'] && num[')']) {
int d = min(num[';'], num[')']);
for (int i = 0; i < d; i++) {
cout << ";-)" << endl;
}
num[';'] -= d;
num['-'] -= d;
num[')'] -= d;
}
if (num[';'] && num['(']) {
int d = min(num[';'], num['(']);
for (int i = 0; i < d; i++) {
cout << ";-(" << endl;
}
num[';'] -= d;
num['-'] -= d;
num['('] -= d;
}
if (num[')']) {
int d = num[')'];
for (int i = 0; i < d; i++) {
cout << ":)" << endl;
}
num[':'] -= d;
num[')'] -= d;
}
if (num['(']) {
int d = num['('];
for (int i = 0; i < d; i++) {
cout << ":(" << endl;
}
num[':'] -= d;
num['('] -= d;
}
cout << "LOL" << endl;
return 0;
}
D. Power play
大意:
给出两个数a和b,范围为1e4
现在要求求出一个1e18以内的数,使得\(a^x==x^b\)
思路:
1e18是个幌子,可以发现x不会超过1e4,所以直接暴力枚举即可
#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read() {
int s = 0, w = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') w = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
return s * w;
}
int const MAXN = 2e5 + 10;
int n, m, T, a, b;
long double eps = 1e-8;
signed main() {
a = read(), b = read();
long double ai = a * 1.0, bi = b * 1.0;
int flg = 0;
for (int i = 1; i <= 1e6; ++i) {
if (fabs(bi * log((long double)i) - (long double)i * log((long double)a)) < eps) {
cout << i;
flg = 1;
break;
}
}
if (!flg) cout << 0;
return 0;
}
E. Printed circuit board
gugugu
F. A word game
sg函数裸题
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
typedef long long LL;
string s;
int a[30];
int f[100];
int sg(int x) {
if (f[x] != -1) return f[x];
unordered_set<int> S;
if (x >= 1) S.insert(sg(x - 1));
if (x >= 2) S.insert(sg(x - 2));
if (x >= 3) S.insert(sg(0));
for (int i = 0;; i++) {
if (!S.count(i)) return f[x] = i;
}
}
int main() {
cin >> s;
memset(f, -1, sizeof f);
for (int i = 0; i < s.size(); i++) {
a[s[i] - 'A']++;
}
int res = 0;
f[0] = 0;
for (int i = 0; i < 26; i++) {
res ^= sg(a[i]);
}
if (res) cout << "Alice" << endl;
else cout << "Bob" << endl;
return 0;
}
G. Hourglass
gugugu
H. Men's showdown
集合nim游戏裸题
#include<bits/stdc++.h>
using namespace std;
int n, k;
int const N = 1e2 + 10, M = 1e4 + 10;
int s[N];
int f[M];
// 记忆化搜索求sg函数
int sg(int x) {
if (f[x] != 0) return f[x];
unordered_set<int> S;
// 计算每个后继状态的sg值
for (int i = 1; i <= 3; ++i) {
int sum = s[i];
if (x >= sum) S.insert(sg(x - sum));
}
// mex运算
for (int i = 0; ; i++)
if (!S.count(i)) return f[x] = i;
}
int main() {
// 读入集合s
s[1] = 1, s[2] = 5, s[3] = 13;
int x;
cin >> x;
int res = sg(x);
if (!res) cout << "1\n";
else cout << "2\n";
return 0;
}
I. Andrew and Python
思路:
交互题,给出一个n*n的棋盘,然后有一个目标点,现在可以进行3种操作:
一种是询问目标点是否是某一个点
一种是询问目标点是否在某一条线段上
一种是询问目标点是否在某一个三角形上及内部
思路:
利用三角形询问进行二分,每次询问一半的三角形,到后面如果无法组成三角形,那么就利用线段进行二分
最后可能会剩下1-3个点,直接暴力询问即可
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int> PII;
inline int read() {
int s = 0, w = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') w = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
return s * w;
}
int const MAXN = 2e5 + 10;
int n, m, T;
PII get_mid(PII x, PII y, PII z) {
double res_x = (1.0 * x.first + 1.0 * y.first) / 2.0;
double res_y = (1.0 * x.second + 1.0 * y.second) / 2.0;
if (z.first < res_x)
res_x = ceil(res_x);
else
res_x = floor(res_x);
if (z.second < res_y)
res_y = ceil(res_y);
else
res_y = floor(res_y);
return {(int)res_x, (int)res_y};
}
int test(PII a, PII b, PII c) {
if ((c.second - b.second) * (b.first - a.first) ==
(b.second - a.second) * (c.first - b.first))
return 1;
else
return 0;
}
int check(PII a, PII b, PII c) {
if (!test(a, b, c)) {
cout << "? 3 " << a.first << " " << a.second << " " << b.first << " "
<< b.second << " " << c.first << " " << c.second << endl;
fflush(stdout);
string s;
cin >> s;
if (s == "Yes")
return 1;
else
return 0;
} else {
if (a == b) {
return 0;
} else {
cout << "? 2 " << a.first << " " << a.second << " " << b.first
<< " " << b.second << endl;
fflush(stdout);
string s;
cin >> s;
if (s == "Yes")
return 1;
else
return 0;
}
}
}
int check2(PII a, PII b, PII c) {
int ab = (a.first - b.first) * (a.first - b.first) +
(a.second - b.second) * (a.second - b.second);
int bc = (b.first - c.first) * (b.first - c.first) +
(b.second - c.second) * (b.second - c.second);
int ac = (a.first - c.first) * (a.first - c.first) +
(a.second - c.second) * (a.second - c.second);
if (ab < 4 && bc < 4 && ac < 4) return 0;
return 1;
}
int Query(PII x) {
cout << "? 1 " << x.first << " " << x.second << endl;
fflush(stdout);
string s;
cin >> s;
if (s == "Yes")
return 1;
else
return 0;
}
void print(PII x) {
cout << "! " << x.first << " " << x.second << endl;
fflush(stdout);
}
signed main() {
cin >> n;
PII a, b, c;
c = {1, 1}, a = {1, n}, b = {n, 1};
if (!check(a, b, c)) c = {n, n};
while (check2(a, b, c)) {
PII mid = get_mid(a, b, c);
if (check(a, c, mid)) {
b = c, c = mid;
} else {
a = b, b = c, c = mid;
}
}
if (Query(a)) {
print(a);
} else if (Query(b)) {
print(b);
} else if (Query(c)) {
print(c);
}
return 0;
}
J. Something that resembles Waring's problem
大意:
给出一个数x,要求将其表示为不超过5个数的立方和的形式,x范围为1e100000
思路:
过于精妙....
来自:https://www.cnblogs.com/hyheng/p/14264678.html
python3写了一发没过 ,应该是科学计数法导致的精度丢失,长了个教训,高精度就用Python2
n = input()
n = int(n)
r = n % 6
r3 = r * r * r
print('5')
print('%d %d %d %d %d' %(r, ((n - r3) / 6 + 1), ((n - r3) / 6 - 1), (-(n - r3) / 6), (-(n - r3) / 6)))
K. Parabolic sorting
大意:
给出n个不相等的数,要求将其排列为前降后升的序列,每次操作可以将相邻的两个点交换,问最小多少次交换可以完成
思路:
对于每个点,考虑将其放到前面下降的区间还是后面上升的区间
如果放到前面区间,那么需要操作的就是前面比他小的数的个数
如果放到后面区间,那么需要操作的就是后面比他小的个数
所以每个点算一下前面后面的个数,取min,最后相加即可
可以用树状数组,线段树来维护
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int const N = 5e5 + 10;
LL c[N], n, a[N], l[N], r[N];
vector<LL> v;
unordered_map<LL, int> H;
int lowbit(int x) { return x & -x; }
void add(int x, int y) {
for (int i = x; i <= n; i += lowbit(i)) c[i] += y;
}
LL query(int x) {
LL res = 0;
for (int i = x; i; i -= lowbit(i)) res += c[i];
return res;
}
int main() {
scanf("%lld", &n);
memset(c, 0, sizeof c);
v.clear();
H.clear();
for (int i = 1; i <= n; ++i) {
scanf("%lld", &a[i]);
v.push_back(a[i]);
}
sort(v.begin(), v.end());
int cnt = 1;
for (int i = 0; i < v.size(); ++i) H[v[i]] = cnt++; // 离散化
LL res = 0;
for (int i = n; i >= 1; --i) { // 计算每个H[a[i]]出现的次数
r[i] = query(H[a[i]] - 1); // 加上H[a[i]-1]出现的总次数
add(H[a[i]], 1); // 次数加一
}
for (int i = n; i >= 1; --i) {
add(H[a[i]], -1);
}
for (int i = 1; i <= n; ++i) { // 计算每个H[a[i]]出现的次数
l[i] = query(H[a[i]] - 1); // 加上H[a[i]-1]出现的总次数
add(H[a[i]], 1); // 次数加一
}
for (int i = 1; i <= n; ++i) {
res += min(r[i], l[i]);
}
cout << res << endl;
return 0;
}