Codeforces Round #266 (Div. 2)

A. Cheap Travel
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Ann has recently started commuting by subway. We know that a one ride subway ticket costs a rubles. Besides, Ann found out that she can buy a special ticket for m rides (she can buy it several times). It costs b rubles. Ann did the math; she will need to use subway n times. Help Ann, tell her what is the minimum sum of money she will have to spend to make n rides?

Input

The single line contains four space-separated integers nmab (1 ≤ n, m, a, b ≤ 1000) — the number of rides Ann has planned, the number of rides covered by the m ride ticket, the price of a one ride ticket and the price of an m ride ticket.

Output

Print a single integer — the minimum sum in rubles that Ann will need to spend.

Sample test(s)
input
6 2 1 2
output
6
input
5 2 2 3
output
8
Note

In the first sample one of the optimal solutions is: each time buy a one ride ticket. There are other optimal solutions. For example, buy threem ride tickets.

题意:Ann要乘坐n次地铁,现在有两种票,一种是b元m次,一种是一次a元,求最少花费多少
思路:这题目意思很简单,但是一些特殊数据不是这个过不了就是那个过不了,代码改来改去最后还是错了,主要原因是思路不清晰,逻辑混乱

这题正确的思路:如果b/m>a的话直接输出n*a,否则n/m算出第二种票最多可以买多少张,然后拿n*a和n/m*b+n%m*a相比较哪个小,如果只是这样的话还是wa,还有一种情况就是你n%m*a>1*b,也就是说再多买一张m票可能花费的更少,因此还需要比较这种情况

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;

int main()
{
    int n,m,a,b;
    cin>>n>>m>>a>>b;

    if(b/m > a) cout<<n*a<<endl;
    else {
        int cent = n/m;
        int ans = min(min(cent*b + n%m*a,n*a),(cent+1)*b);
        cout<<ans<<endl;
    }
    return 0;
}

B. Wonder Room
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

The start of the new academic year brought about the problem of accommodation students into dormitories. One of such dormitories has aa × b square meter wonder room. The caretaker wants to accommodate exactly n students there. But the law says that there must be at least 6 square meters per student in a room (that is, the room for n students must have the area of at least 6n square meters). The caretaker can enlarge any (possibly both) side of the room by an arbitrary positive integer of meters. Help him change the room so as all nstudents could live in it and the total area of the room was as small as possible.

Input

The first line contains three space-separated integers na and b (1 ≤ n, a, b ≤ 109) — the number of students and the sizes of the room.

Output

Print three integers sa1 and b1 (a ≤ a1b ≤ b1) — the final area of the room and its sizes. If there are multiple optimal solutions, print any of them.

Sample test(s)
input
3 3 5
output
18
3 6
input
2 4 4
output
16
4 4

题意:寝室里面有n个人,每个人必须占6m^2大小,也就是寝室面积不小于6n,同时给出初始长和宽a,b,要求最后a<=a1,b<=b1,求最小的a1*b1满足条件

思路:题目n=10^9,如果直接枚举o(n),会TLE,但是我们考虑到6n最大不超过6*10^9,也就是说a*b最大不超过6*10^9,那么我们假设一开始a<b的话,那么我们只需要枚举a------a+sqrt(6*n),o(sqrt(n))的时间可以过

开始就假设a<b这样可以不用分类讨论,用flag标记一下,最后swap一下就行

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long LL;

int main()
{
    LL n,a,b;
    int flag = 0;
    LL a1,b1;
    cin>>n>>a>>b;
    if(a > b)
    {
        swap(a,b);
        flag = 1;
    }
    LL sum = 6*n;
    LL INF = 1LL<<62;
    for(LL i = a; i <= a + 50000LL; i++)
    {
        LL tb = sum/i + (sum%i != 0);//如果不能整除的话b1的值要加1,否则b1*a<sum
        tb = max((LL)b,tb);
        LL mins = tb * i;
        if(mins < INF)
        {
            INF = mins;
            a1 = i;
            b1 =tb;
        }
    }
    if(flag) swap(a1,b1);
    cout<<INF<<endl;
    cout<<a1<<" "<<b1<<endl;
    return 0;
}

C. Number of Ways
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You've got array a[1], a[2], ..., a[n], consisting of n integers. Count the number of ways to split all the elements of the array into three contiguous parts so that the sum of elements in each part is the same.

More formally, you need to find the number of such pairs of indices i, j (2 ≤ i ≤ j ≤ n - 1), that .

Input

The first line contains integer n (1 ≤ n ≤ 5·105), showing how many numbers are in the array. The second line contains n integers a[1],a[2], ..., a[n] (|a[i]| ≤  109) — the elements of array a.

Output

Print a single integer — the number of ways to split the array into three parts with the same sum.

Sample test(s)
input
5
1 2 3 0 3
output
2
input
4
0 1 -1 0
output
1
input
2
4 1
output
0

题意:求一段连续的数平均分成连续的三段,求有多少种划分方法?

思路:因为是连续的,因此把每个位置求和,首先判断总和是否能被3整出,如果不能直接输出0,否则找出sum[i]=sum[n]/3*2之前总共出现过多少次sum[i] = sum[n]/3,因为有多少个sum[n]/3就有多少种,例如:1 2 0 3 3 sum[4] = 6 = sum[n]/3*2,它前面有两个sum[i] = sum[n]/3,120 3 3或者12 03 3,看出来了没有?有n个sum[n]/3就代表有n-1个块加起来是0,那么放左边放右边都不影响

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
using namespace std;
typedef long long LL;
const int Max = 5*100000+10;
LL sum[Max];
int main()
{
    int n,a;
    cin>>n;
    sum[0] = 0;
    for(int i = 1; i <= n; i++)
    {
        cin>>a;
        sum[i] =sum[i-1] + a;
    }

    if(sum[n]%3)
    {
        cout<<0<<endl;
    }
    else
    {
        LL one = sum[n]/3,two = one*2,cent = 0,ans = 0;
        for(int i = 1; i < n ; i++)//i到N-1就行了
        {
             if(sum[i] == two)//有一点要注意这个判断必须放在前面,因为有可能one = two ,如果先cent++再加的话会多算
            {
                ans += cent;
            }

            if(sum[i] == one)
            {
                cent++;
            }


        }

        cout<<ans<<endl;

    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值