Codeforces Round #102 (Div. 2) 题解

A.

解一个方程。

还是厚颜无耻地暴力吧~

#include <iostream>
using namespace std; int r1, r2, c1, c2, d1, d2;
bool chk(int x1, int x2, int x3, int x4)
{
int ok = 1;
if(x1 == x2 || x1 == x3 || x1 == x4 || x2 == x3 || x2==x4 || x3==x4) ok = 0;
if(x1 + x2 != r1) ok = 0;
if(x3 + x4 != r2) ok = 0;
if(x1 + x3 != c1) ok = 0;
if(x2 + x4 != c2) ok = 0;
if(x1 + x4 != d1) ok = 0;
if(x2 + x3 != d2) ok = 0;
return ok;
} int main()
{
cin >> r1 >> r2 >> c1 >> c2 >> d1 >> d2;
for(int x1=1;x1<=9;x1++)for(int x2=1;x2<=9;x2++)
for(int x3=1;x3<=9;x3++)for(int x4=1;x4<=9;x4++) {
if(chk(x1, x2, x3, x4)) {
cout << x1 << " " << x2 << endl;
cout << x3 << " " << x4 << endl;
return 0;
}
}
cout << -1 << endl;
}

B.

可以练一练码力的题。

#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
char s[202];int minu = 0, n, dot;
vector<char> v;
void rush() {
if(s[1] == '-') minu = 1;
else return; for(int i=1;i<=n-1;i++) {
s[i] = s[i+1];
}
n --; dot --;
}
int main()
{
scanf("%s", s+1);
n = strlen(s+1);
dot = n+1;
for(int i=1;i<=n;i++)
{
if(s[i] == '.') dot = i;
}
rush();
v.push_back(s[1]);
for(int i=2;i<=min(n, dot+2);i++) {
if((dot - i) % 3 == 0 && dot != i) {
v.push_back(',');
}
v.push_back(s[i]);
}
if(dot == n-1) v.push_back('0');
if(dot == n+1) v.push_back('.'), v.push_back('0'), v.push_back('0');
if(minu) printf("(");
printf("$");
for(int i=0;i<v.size();i++) {
printf("%c", v[i]);
}
if(minu) printf(")");
}

C. 给出X,求Y-X的最大值与最小值。

X = A * B * C [A,B,C皆为正整数]

Y = (A+1) * (B+2) * (C+2) [取名为①式]

题解:

我们可以用sqrt(X)的复杂度枚举A。

展开吧!①式!

然后就会发现。B, C越接近,Y越小。【根据基本不等式得到的】

然后开始枚举B的值。【枚举姿势:从sqrt(X/A)向1枚举B】

#include <cmath>
#include <iostream>
using namespace std;
typedef long long LL;
LL n, minc = 1e15, maxc = -1e15;
void solve(LL a) {
LL t = n / a;
maxc = max(maxc, (a+1)*(t+2)*(LL)3 - n);
LL tmp = (LL)sqrt(t) + 1;
for(LL b = tmp; b >= 1; b--) {
if(t % b == 0) {
minc = min(minc, (a+1)*(b+2)*(t/b+2) - n);
}
} }
int main()
{
cin >> n;
for(LL a = 1; a * a <= n; a ++) {
if(n % a == 0) {
solve(a);
solve(n/a);
}
}
cout << minc << " " << maxc << endl;
}

  

D.

很有趣的一题!

给一个n * m的棋盘。往上放棋子。

然后往上放棋子。如果一个骑士可以从A跳到B。那么A和B不能同时放棋子。

问最多可以放几个棋子。

思路:

先将棋盘按照国际象棋棋盘的方式染色。【就是黑白交错的那种啦!】

然后发现骑士从黑格子只能跳到白格子。从白格子只能跳到黑格子。

所以我们可以在所有黑格子上放棋子。于是可以放$\frac{(mn+1)}{2}$个棋子

不妨设m <= n

当m=1时,$ans = n$

当m=2时,

ans = n+1 (n为奇数)

ans = n+2 (n%4=2)

构造方法如下:

AABBAABBAA

AABBAABBAA

A表示放置棋子。B表示不放棋子

#include <iostream>
using namespace std;
int n, m; int main()
{
cin >> n >> m;
int ans = (m*n+1)/2;
if(n > m) swap(n, m);
if(n == 1) ans = m;
if(n == 2) {
if(m % 2 == 1) ans = m+1;
if(m % 4 == 2) ans = m+2;
}
cout << ans << endl;
}

  

上一篇:MongoDB的安装和配置成服务的三种方法


下一篇:【leetcode❤python】263. Ugly Number