atcoder补题

文章介绍了四个编程问题,涉及动态规划解决最长左/右金字塔序列,五进制数的生成,链表操作模拟排队,以及使用贪心策略计算做菜问题。最后一个题目是关于路线差分和桥梁优化的计算。
摘要由CSDN通过智能技术生成

目录

1,金字塔序列 

2.五进制 

3.排队 

4.做菜 

5.差分


金字塔序列

1,金字塔序列 

主要考察动态规划,dp1[i]表示i作为中心位置最长的左金字塔序列,dp2[i]表示i作为中心位置最长的右金字塔序列,dp1,dp2全都初始化为0,对第i个位置答案是min(dp1[i],dp2[i]),而最终的答案要取每个位置作为中心的最大值

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=2e5+5;
int a[maxn],dp1[maxn],dp2[maxn];
signed main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    cin>>a[i];
    for(int i=1;i<=n;i++)
    {
        dp1[i]=min(dp1[i-1]+1,a[i]);
    }
    for(int i=n;i>=1;i--)
    {
        dp2[i]=min(dp2[i+1]+1,a[i]);
    }
    int ans=-1;
    for(int i=1;i<=n;i++)
    {
        ans=max(ans,min(dp1[i],dp2[i]));
    }
    cout<<ans;
    return 0;
}

五进制

2.五进制 

这个题考察五进制,依题意,一个好整数要求每一位都是偶数(0,2,4,6,8),相当与五进制分别对应五进制里的0,1,2,3,4但是0在好整数中表示1,所以求第n个好整数,相当于求第n-1个五进制数,这最后wa了一个点,因为第1个二进制数相当于五进制中的0,而0不用分解,所以没输出,故第一个二进制数需要特判

#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int n;
    cin>>n;
    string ans="";
    n--;
    if(n==0)
    ans="0";
    char hash[5]={'0','2','4','6','8'};
    while (n)
    {
        int t=n%5;
        ans=hash[t]+ans;
        n/=5;   
    }
    cout<<ans;
    return 0;
}

 排队

3.排队 

这题就是一条链,就看你看得出来不

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=3e5+5;
int ha[maxn],a[maxn];
signed main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int n;
    cin>>n;
    int flag;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        if(a[i]==-1)
        flag=i;
        else
        ha[a[i]]=i;
    }
    cout<<flag<<" ";
    for(int i=0;i<n-1;i++)
    {
        cout<<ha[flag]<<" ";
        flag=ha[flag];
    }
    return 0;
}

做菜

4.做菜 

这个题思路是,先枚举a菜,分别看只用哪种调料,a菜最多可以做多少道,再取min,求出用上每种材料a菜最多可以做多少道hami,再从0到hami遍历a菜做多少道,内层循环遍历用剩下的材料,b菜做多少道,总道数就是i加hbmi,取每种情况的最大值

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e6+5;
int q[maxn],a[maxn],b[maxn];
signed main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)cin>>q[i];
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++)cin>>b[i];

    int hami=1000000000;
    for(int i=1;i<=n;i++)
    {
        if(a[i]==0)continue;
        hami=min(hami,q[i]/a[i]);
    }
    int ans=-1;
    for(int i=0;i<=hami;i++)//枚举a做多少道
    {
        int hbmi=1000000000;
        for(int j=1;j<=n;j++)//枚举每种情况b最多为多少道
        {
            if(b[j]==0)continue;
            hbmi=min(hbmi,(q[j]-a[j]*i)/b[j]);//剩下的材料b菜每道最多可以做多少
        }
        ans=max(ans,i+hbmi);
    }
    cout<<ans;
    return 0;
}

差分

5.差分

这题差分,不太会

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
const int maxn=2e5+5;

int n,m;
int des[maxn];
ll cst[maxn];//删除i->i+1边的代价 
ll ans=1e18,lst=0;

int main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++)
		cin>>des[i];//读入路线
	for(int i=2,l,r,t;i<=m;i++){
		l=min(des[i],des[i-1]);//取小
		r=max(des[i],des[i-1]);//取大
		
		if(r-l<=n+l-r){//原本走l->r 
			t=n+l-r-(r-l);//加的代价
			lst+=r-l;//路数
			cst[l]+=t;
			cst[r]-=t;//差分加工
		}
		else {
			t=r-l-(n+l-r);
			lst+=n+l-r;//走的是n+l-r,没拆桥时正常计数
			cst[r]+=t;
            cst[n+1]-=t;
			cst[1]+=t;
			cst[l]-=t;//1~l,r~n都要加代价
		}
	}
	
	for(int i=1;i<=n;i++){
		cst[i]+=cst[i-1];//每个点都是代价,取最小的
		ans=min(ans,cst[i]);//取代价的最小值
	}
	cout<<lst+ans;
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值