• [CSP-S模拟测试]:折纸(模拟)


    题目描述

    小$s$很喜欢折纸。
    有一天,他得到了一条很长的纸带,他把它从左向右均匀划分为$N$个单位长度,并且在每份的边界处分别标上数字$0sim n$。
    然后小$s$开始无聊的折纸,每次他都会选择一个数字,把纸带沿这个数字当前所在的位置翻折(假如已经在边界上了那就相当于什么都不做)。
    小$s$想知道$M$次翻折之后纸带还有多长。


    输入格式

    第一行包含两个正整数$N$和$M$,表示纸带的长度和操作的次数。

    接下来的一行包含$M$个整数$D_i$,其中$D_i$表示第$i$次选择的数字。


    输出格式

    输出文件只有一个数字,即纸带最后的长度。


    样例

    样例输入:

    5 2
    3 5

    样例输出:

    2


    数据范围与提示

    $60\%$的数据中$Nleqslant 3,000,Mleqslant 3,000$。
    $100\%$的数据中$Nleqslant {10}^{18},Mleqslant 3,000$。


    题解

    $60\%$算法:

    直接模拟翻折过程,记录每一个点现在的位置即可,每次暴力更新。

    记得初始化。

    时间复杂度:$Theta(N imes M)$。

    期望得分:$60$分。

    实际得分:$60$分。

    $100\%$算法:

    发现我们并不用关心每个纸带的位置,只用考虑当前操作的位置就好了。

    每次翻折之后对所有的操作进行$Theta(M)$重标号即可,至于式子$D_j=abs(D_i-D_j)$。

    时间复杂度:$Theta(m^2)$。

    期望得分:$100$分。

    实际得分:$100$分。


    代码时刻

    #include<bits/stdc++.h>
    using namespace std;
    long long n,m;
    long long l,r;
    long long wzc[5000];
    int main()
    {
    	scanf("%lld%lld",&n,&m);
    	l=0,r=n;
    	for(int i=1;i<=m;i++)
    	{
    		scanf("%lld",&wzc[i]);
    		for(int j=1;j<i;j++)
    			if(wzc[j]>=wzc[i])
    				wzc[i]=2LL*wzc[j]-wzc[i];
    		r=max(r,2LL*wzc[i]-l);
    		l=wzc[i];
    	}
    	printf("%lld",r-l);
    	return 0;
    }
     

    rp++

  • 相关阅读:
    Http中的patch
    如何实现腾讯地图的路径规划功能?
    各类数据库分页SQL语法
    ABC222F
    ABC222 G
    LG5308 [COCI2019] Quiz(wqs二分+斜率优化DP)
    [USACO21OPEN] Portals G(Kruskal)
    【做题笔记】SP27379 BLUNIQ
    【做题笔记】CF938C Constructing Tests
    CSP-J/S2021 自闭记
  • 原文地址:https://www.cnblogs.com/wzc521/p/11366052.html
Copyright © 2020-2023  润新知