Codeforces Round #476 (Div. 2)

题目链接

A题 解题思路:


给出k , n, s, p 。 n 个人,
k个人,一个人需要 s 个纸飞机 ,一包纸里有 p 张纸,而且纸不能共享,求需要几包纸。s 和 p ,求出一个人需要几张纸,然后 * k ,最后再 / p 然后最后需要多少包纸。


代码:


#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const long long M = 1e9 + 7;

const int N = 300;

typedef long long ll ;


int main(){
    int k , n , s , p;
    cin>>k>>n>>s>>p;
    int res = 0;
    if (n % s != 0){
        res = n / s + 1;
    }
    else{
        res = n / s;
    }
    res *= k;
    int num = 0;
    if (res % p != 0){
        num = res / p + 1;
    }
    else{
        num = res / p;
    }
    cout<<num<<endl;
    return 0;
}


B题 解题思路:


枚举做法,遍历所有点,求符合要求点的最大点,因此先按行遍历,让符合的点就 +1,然后按列遍历,让符合的再 +1,然后遍历所有的点,求出最大值。


代码:


#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const long long M = 1e9 + 7;

const int N = 105;

typedef long long ll ;

char mp[N][N];
int ans[N][N];

int main(){
    int k, n;
    scanf("%d%d",&n,&k);
    for (int i = 0; i < n; i++){
        scanf("%s",mp[i]);
    }
    for (int i = 0; i < n; i ++){
        int x = 0;
        for (int j = k - 1; j < n; x++,j++){
            int q = 0;
            for (int p = x ; p <= j;p ++){
                if (mp[i][p] == '#'){
                    q = 1;
                    break;
                }
            }
            if (q == 0){
                for (int p = x; p <= j; p++){
                    ans[i][p] += 1;
                }
            }
        }
    }
    for (int i = 0; i < n; i++){
        int x = 0;
        for (int j = k - 1; j < n; x ++ , j ++){
            int q = 0;
            for (int p = x; p <= j; p ++){
                if (mp[p][i] == '#'){
                    q = 1;
                    break;
                }
            }
            if (q == 0){
                for (int p = x; p <= j; p ++){
                    ans[p][i] += 1;
                }
            }
        }
    }
    int mx = ans[0][0];
    int xx = 1;
    int yy = 1;
    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
            if (ans[i][j] > mx){
                xx = i + 1;
                yy = j + 1;
                mx = ans[i][j];
            }
        }
    }
    printf("%d %d\n",xx,yy);
    return 0;
}


C题 解题思路:


数学公式,同时有些贪心。贪心就是第一个人多拿一次,其他的人少拿一次,也就是第一个人拿 i 次,其他人拿i - 1 次,k 个人 一次分 x 个,因此 推出公式: ( i - 1 ) * k * x + x <= n,这时要求 x 最大,因此 x <= n / ((i - 1) * k + 1), 然后我们可以遍历,从 1 到 d,这里的问题是
如果num = 0,直接break,因为 k * d 爆long long 了。


代码:


#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const long long M = 1e9 + 7;

const int N = 300010;

typedef long long ll ;

int main(){
    ll n , k, m , d;
    scanf("%lld%lld%lld%lld",&n,&k,&m,&d);
    ll mx = 0;
    for (int i = 1; i <= d; i++){
        ll num = n / ((i - 1) * k +  1);
        if (num == 0) break;
        num = min(num , m);
        mx = max(mx,num * i);
    }
    printf("%lld",mx);
    return 0;
}


D题 解题思路:


超级思维题,利用前缀和,对于长 l 的窗口,我们不断向右移动,然后求出最大值,即最终的最大值


代码:


#include <map>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const long long M = 1e9 + 7;

const int N = 100010;

typedef long long ll ;

int ans[N];

int main(){
    int l , w;
    int res = 1e9;
    scanf("%d%d",&w,&l);
    for (int i = 1; i <= w - 1; i++){
        scanf("%d",&ans[i]);
        ans[i] += ans[i - 1];
    }
    for (int i = l; i < w; i ++){
        res = min(res,ans[i] - ans[i - l]);
    }
    printf("%d\n",res);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值