习题日常第十八练

1道路铺设(题目链接

这个是思维题,代码特别简单。第一个数必定是要加入天数的,之后,每一个数只要大于它的前一个,天数就得加上他俩的差值,因为这时候前面那个小的需要的天数不足以让大以及以后的比这个大的消耗为0,此时先计算需要额外的大的数需要天数,然后再以此类推判断后面的数即可。代码如下。

#include<cmath>
#include <iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<vector>
#include<set>
#include<map>
#include<cstring>
#include<math.h>
#include<stack>
#include<algorithm>
#include<queue>
#include<bitset>
#include<sstream>
#define ll long long int
const int mod=100003;
using namespace std;
int a[100010],n,m;
ll ans=0;
int main()
{
    ios::sync_with_stdio(false);
    int i,j,t;
    cin>>n;
    memset(a,0,sizeof(a));
    for(i=1;i<=n;i++)
        cin>>a[i];
    for(i=1;i<=n;i++)
    {
        if(a[i]-a[i-1]>0)
            ans+=a[i]-a[i-1];

    }
    cout<<ans;
  return 0;
}

2操作系统(题目链接

这个题是个模拟题,可能还是没有优先队列的思维吧,看过题解以后才做出来的。边输入边处理,每次处理这次输入的开始时间之前时间的情况。注意每一次要让代表当前时间的指针指向这次的开始。代码如下。

#include<cmath>
#include <iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<vector>
#include<set>
#include<map>
#include<cstring>
#include<math.h>
#include<stack>
#include<algorithm>
#include<queue>
#include<bitset>
#include<sstream>
#define ll long long int
const int mod=100003;
using namespace std;
int a[100010],n,m;
ll ans=0;
struct node
{
    int b,s,w,z;
    bool operator < (const node x) const
    {
       if(x.z==this->z)
        return x.s<this->s;
       else
        return x.z>this->z;
    }
}t[2000010];
priority_queue<node> p;
int main()
{
    ios::sync_with_stdio(false);
    int i,j;
    i=0;
    int ma;
    cin>>t[i].b>>t[i].s>>t[i].w>>t[i].z;
    ma=t[i].s;
    p.push(t[i]);
    while(cin>>t[i].b>>t[i].s>>t[i].w>>t[i].z)
    {
        int e=t[i].s-ma;
        while(!p.empty()&&ma<t[i].s)
        {
            node lp=p.top();
            p.pop();
            if(lp.w<=e)
            {
                e=e-lp.w;
                ma=ma+lp.w;
                cout<<lp.b<<" "<<ma<<endl;
            }
            else
            {
                lp.w=lp.w-e;
                ma=t[i].s;
                p.push(lp);
            }
        }
        ma=t[i].s;
      p.push(t[i]);
    }
   while(!p.empty())
   {
      node lp=p.top();
      cout<<lp.b<<" "<<ma+lp.w<<endl;
      ma+=lp.w;
      p.pop();
   }

  return 0;
}

3数列(题目链接

这个题与其说是个数论题,还不如说是个找规律题。如果从1开始看这个数列,第i个数就是i转化为2进制以后再用k进制输出即可。代码如下(记得开long long )。

#include<cmath>
#include <iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<vector>
#include<set>
#include<map>
#include<cstring>
#include<math.h>
#include<stack>
#include<algorithm>
#include<queue>
#include<bitset>
#include<sstream>
#define ll long long int
const int mod=100003;
using namespace std;
ll a[100010];
int main()
{
    ios::sync_with_stdio(false);
    ll i,j,n,m;
     cin>>n>>m;
     i=0;
     while(m)
     {
         a[i++]=m%2;
         m/=2;
     }
     m=1;
     ll ans=0;
     for(j=0;j<i;j++)
     {
         ans+=a[j]*m;
         m*=n;
     }
     cout<<ans;
  return 0;
}

4选择客栈(题目链接

这是个思维题吧。感觉是给O(N^2)的题,但是可能O(N)解决。是个典型的用空间换时间的题。边输入边处理,主要思想是根据当前颜色寻找之前满足条件的颜色数目,最后相加。用数组存下每一个颜色上一次出现的位置,再存下这个颜色当前出现的次数以及这个颜色,用一个标记来标适合咖啡厅最靠后的位置,每一次看咖啡厅是否满足要求,满足要求则更新标记。然后看标记是否在当前颜色的上一个位置后面或者正在那个位置,如果在的话,上一个位置也对于当前位置是个合理的位置,则将这个颜色之前满足的值加一。每次把最终解加上当前颜色之前满足条件的值即可。代码如下。

#include<cmath>
#include <iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<vector>
#include<set>
#include<map>
#include<cstring>
#include<math.h>
#include<stack>
#include<algorithm>
#include<queue>
#include<bitset>
#include<sstream>
#define ll long long int
const int mod=100003;
using namespace std;
ll a[100010],c[100010],d[100010];
int main()
{
    ios::sync_with_stdio(false);
    ll i,j,n,m,x,y,k,p,ans=0;
    memset(a,0,sizeof(a));
    memset(c,0,sizeof(c));
    memset(d,0,sizeof(d));
   cin>>n>>k>>p;
   int now=0;
   for(i=1;i<=n;i++)
   {
       int po=0;
       cin>>x>>y;
       if(y<=p)
        now=i;
        if(now>=a[x])
           d[x]=c[x];
           a[x]=i;
        ans+=d[x];
        c[x]++;
   }
   cout<<ans;
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值