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;
}

  

 

转载于:https://www.cnblogs.com/RUSH-D-CAT/p/6909558.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值