Codeforces Round #523 (Div. 2) ABCD

A.Cions

题意:这道题目的题意就是输入一个n和一个S,然后你拥有1到n的硬币,并且有无数个。
这道题很简单,就直接给代码了

#include<iostream>
using namespace std;


int main()
{

    long long int i=0,n;
    cin>>i>>n;
    int flag=0;
    if(n%i==0)
        flag=1;
    long long int ans=0;
    ans=flag?n/i:n/i+1;
    cout<<ans<<endl;
}

B. Views Matter

题意:就是长为n宽为m的长方形,然后后面的5的数字代表每一列有都少个长方形,然后问在不影响俯视图和右视图的情况下可以移动多少个格子
思路:做这题,自己也自闭了,一直想不出方法,思考着acm这东西适合我么。最后悄咪咪看了一下答案,基本是一道贪心,我们先对列进行排序,从小到大,然后从第一列开始余留下(1,1),第二列余留下(2,2)。。。(,每次加一如果不够高就不加了),直到最后一列,就可以去掉前面得到的高度,就得到答案了。

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll a[100010];
int main()
{
    ll n,m;
    cin>>n>>m;
    ll i;
    for(i=0;i<n;i++)
    {
        cin>>a[i];
    }
    sort(a,a+n);
    ll sum=0;
    ll cnt=0;
    ll now=0;
    for(i=0;i<n-1;i++)
    {
        sum+=a[i]-1;
        if(a[i]>=cnt+1)
            cnt++;
    }
    sum+=cnt;
    if(a[i]<=cnt)
        sum--;
    cout<<sum<<endl;
    return 0;
}

C. Multiplicity

题意:如果一个数列,a1,a2,…ai,其中ai都能被i整除,那么他就是一个好数列,题目要求一个数列里他的子数列有一个好数列
题解:虽然一开始就直到时dp也想出了改变的方式,基本dp[i][j],意思时第1个到第i个数中组成长为j的子数列个数,但是写完后就wa了,然后我就去找答案了,最后发现了神奇的东西,直接找到每个数的因子,然后直接找。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>

const int maxn=1e6+50;

const int mod=1e9+7;
using namespace std;
long long int dp[maxn];
long long int a[maxn];

vector<int> v[maxn];

int main()
{
    for(int i=1; i<maxn; i++)
    {
        for(int j=i; j<maxn; j+=i)
        {
            v[j].push_back(i);
        }
    }
    long long int n;
    scanf("%lld",&n);
    long long int i;
    long long int j=0;
    for(i=1; i<=n; i++)
        scanf("%lld",&a[i]);
    for(i=1; i<=n; i++)
        for(j=v[a[i]].size()-1; j>=0; j--)
        {
            if(v[a[i]][j]<=i)
            {
                if(v[a[i]][j]==1)
                {
                    dp[1]=dp[1]+1;

                }
                else
                {
                    dp[v[a[i]][j]]=(dp[v[a[i]][j]-1]+dp[v[a[i]][j]])%mod;
                }
            }
        }

    long long int ans=0;
    for(i=0; i<=n; i++)
    {
        ans+=dp[i];
        if(ans>mod)
            ans%=mod;
    }
    cout<<ans<<endl;


}

D. TV Shows

题意:这题就是一个人要看电视,而且他每一台都要看,然后你可以租电视,租电视第一分钟价格会不一样,后面每一分钟都按照另外一个价格算。问最少花费。
题解:一开始我时想着用优先队列,然后慢慢模拟,模拟了快一个小时,还是错了,以为自己写了个假的算法,找了下答案,原来可以用set,和map,进行二分查找。

#include<iostream>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
typedef long long ll;
struct node{
ll x;
ll y;
bool operator<(node n)
{
    if(x==n.x)
        return y<n.y;
    else
        return x<n.x;
}
}n[100010];
const ll mod=1000000007;



int main()
{
    ll m,x,y;
    cin>>m>>x>>y;
    ll i;
    for(i=0;i<m;i++)
        cin>>n[i].x>>n[i].y;
    ll sum=0;
    set<ll> s;
    map<ll,int> mp;
    sort(n,n+m);
    s.insert(n[0].y);
    mp[n[0].y]++;
    sum=(sum+(n[0].y-n[0].x)*y+x)%mod;
    for(i=1;i<m;i++)
    {
        set<ll>::iterator it=s.lower_bound(n[i].x);
        if(it==s.begin())
        {
            sum=(sum+(n[i].y-n[i].x)*y+x)%mod;
            mp[n[i].y]++;
            s.insert(n[i].y);
        }
        else
        {
            it--;
            if((n[i].x-*it)*y<=x&&n[i].x>*it)
            {
                sum=(sum+(n[i].y-*it)*y)%mod;
                mp[*it]--;
                if(mp[*it]==0)
                    s.erase(*it);
                mp[n[i].y]++;
                s.insert(n[i].y);
            }
            else
            {
                sum=(sum+(n[i].y-n[i].x)*y+x)%mod;
                mp[n[i].y]++;
                s.insert(n[i].y);

            }


        }
    }
    cout<<sum<<endl;



    return 0;
}

总结:这次基本就会一题,感觉凉了,在dp,贪心,模拟感觉自己好菜,还是要多练

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值