Codeforces Round #470ABC 题解

13 篇文章 0 订阅
2 篇文章 0 订阅

A - Protect Sheep

  CodeForces - 948A (暴力)

水题不贴代码了,暴力判断羊的相邻的四个点有没有狼,如果没有的话暴力把所有空的点填上狗- -


B - Primal Sport

  CodeForces - 948B (数学)

Alice and Bob begin their day with a quick game. They first choose a starting number X0 ≥ 3 and try to reach one million by the process described below. 

Alice goes first and then they take alternating turns. In the i-th turn, the player whose turn it is selects a prime number smaller than the current number, and announces the smallest multiple of this prime number that is not smaller than the current number.

Formally, he or she selects a prime p < Xi - 1 and then finds the minimum Xi ≥ Xi - 1 such that p divides Xi. Note that if the selected prime p already divides Xi - 1, then the number does not change.

Eve has witnessed the state of the game after two turns. Given X2, help her determine what is the smallest possible starting number X0. Note that the players don't necessarily play optimally. You should consider all possible game evolutions.

Input

The input contains a single integer X2 (4 ≤ X2 ≤ 106). It is guaranteed that the integer X2 is composite, that is, is not prime.

Output

Output a single integer — the minimum possible X0.

Input
14
Output
6
Input
20
Output
15
Input
8192
Output
8191

先顺着模拟一遍过程:

给你一个X0,找一个P1(<X0),X1=P1*t(t>=1),满足X1>=X0,且t取尽量小

已知这个X1,找一个P2(<X1),X2=P2*m(m>=1),满足X2>=X1,且m取尽量小

题目给出X2,倒推出满足要求的X0的最小值。

倒着看,第二次选择的素数为P2(P2<X1),且P2乘上一个数(k)刚好不小于X1,且这个乘积的结果就是X2,那么可以推出X1的范围在[P2*(k-1)+1,P2*k]之间,代入P2*k=X2,推得X1的范围在[X2-P2+1,X2]之间。 同理,推得X0的范围在[X1-P1+1,X1]之间。即X0min=X1-P1+1。

根据X0min的表达式,第一次求的P2应该取最大值(扩大X1的范围),即求X2的最大素数因子,可以利用埃筛打表。确定X1的范围后,注意,这里不能直接取X1的边界min值,因为P1会根据X1的取得而变化。假如X1可以取到20和21,根据20求出的X0=15,而根据21求出的X0则等于15。遍历一遍X1即可。

#include <iostream>
#include <cmath>
using namespace std;
const int N=1000005;
int max_prime[N];
int vis[N];
void get_prime()//埃筛打表求一个数的最大质因数
{
    for(int i=2;i<N;i++)
    {
        if(!vis[i])
        {
            max_prime[i]=i;
            for(int j=i*2;j<N;j+=i)
            {
                vis[j]=1;max_prime[j]=i;
            }
        }
    }
}


int main()
{
    get_prime();
    int x2;
    int t=0;
    cin>>x2;
    int x1=x2-max_prime[x2]+1;//x1min
    int tt=0;
    int ans=9999999;
    for(int i=x1;i<=x2;i++)//遍历x1的取值范围
    {
        int tem=max_prime[i];
        ans=min(ans,i-tem+1);
    }
    cout<<ans<<endl;
}

C - Producing Snow

  CodeForces - 948C(数据结构)

Alice likes snow a lot! Unfortunately, this year's winter is already over, and she can't expect to have any more of it. Bob has thus bought her a gift — a large snow maker. He plans to make some amount of snow every day. On day i he will make a pile of snow of volume Vi and put it in her garden.

Each day, every pile will shrink a little due to melting. More precisely, when the temperature on a given day is Ti, each pile will reduce its volume by Ti. If this would reduce the volume of a pile to or below zero, it disappears forever. All snow piles are independent of each other. 

Note that the pile made on day i already loses part of its volume on the same day. In an extreme case, this may mean that there are no piles left at the end of a particular day.

You are given the initial pile sizes and the temperature on each day. Determine the total volume of snow melted on each day. 

Input

The first line contains a single integer N (1 ≤ N ≤ 105) — the number of days. 

The second line contains N integers V1, V2, ..., VN (0 ≤ Vi ≤ 109), where Vi is the initial size of a snow pile made on the day i.

The third line contains N integers T1, T2, ..., TN (0 ≤ Ti ≤ 109), where Ti is the temperature on the day i.

Output

Output a single line with N integers, where the i-th integer represents the total volume of snow melted on day i.

Examples
Input
3
10 10 5
5 7 2
Output
5 12 4
Input
5
30 25 20 15 10
9 10 12 4 13
Output
9 20 35 11 25
Note

In the first sample, Bob first makes a snow pile of volume 10, which melts to the size of 5 on the same day. On the second day, he makes another pile of size 10. Since it is a bit warmer than the day before, the first pile disappears completely while the second pile shrinks to 3. At the end of the second day, he has only a single pile of size 3. On the third day he makes a smaller pile than usual, but as the temperature dropped too, both piles survive till the end of the day.


第i天堆一个雪人,大小为vi(堆的这一天雪人也会融化),第i天每个雪人的融化量为ti,输出第i天的融化量

暴力复杂度O(n^2),tle了。。。

融化有两种情况,第一种融化量为ti,第二种雪人的大小小于ti,融化量为雪人的大小。其实只要判断这个雪人融没融完就ok了。。

为了降低复杂度,不能暴力每天减来判断雪人有没有融完。

假设第i天堆了一个雪人vi,第j(j>i)天的时候,就是判断ti和从第i天到第j天融化量的总和,这里需要设置一个sum数组,sum[i]表示从第1天到第i天的融化总量,这样只要判断vi和(sum[j]-sum[i])的大小就可以判断第j天雪人是否融化了。

这就建立了一个优先队列的模型,符合要求的(vi>(sum[j]-sum[i]))放在队列里,用队列的size*ti,不符合要求的pop出来。

#include <iostream>
#include <vector>
#include <queue>
using namespace std;
#define ll long long
priority_queue<ll,vector<ll>,greater<ll> >q;//升序优先队列
const int N=100005;
ll v[N];
ll t[N];
ll sum[N];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>v[i];
    }
    for(int i=1;i<=n;i++)
    {
        cin>>t[i];
        sum[i]=sum[i-1]+t[i];
    }
    int flag=1;
    for(int i=1;i<=n;i++)//i表示第几天
    {
        ll res=0;
        q.push(sum[i-1]+v[i]);
        while(!q.empty()&&q.top()<=sum[i])
        {
            res+=q.top()-sum[i-1];
            q.pop();
        }
        res+=q.size()*t[i];
        if(flag)
        {
            flag=0;
        }
        else
        {
            cout<<' ';
        }
        cout<<res;
    }

    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值