重复刷新相反数求最大和

题目描述 Description
给你n个数,并且可以对其中任意M个数求相反数,并且这个操作可以执行任意多次,求这串数的和的最大值
输入描述 Input Description
第一行是两个整数n,m
第二行是n个整数
输出描述 Output Description
一个整数,这串数的和的最大值
样例输入 Sample Input
3 2
-3 -2 -1
样例输出 Sample Output
4
数据范围及提示 Data Size & Hint
保证在整形范围内,n>=m>=1(ps:其实不算特大。。。。)
时间限制: 2 s
空间限制: 16000 KB

评级:一道非常好玩的神题。。。会让人想起童年玩过的游戏。
题解:这个题仔细分析之后会发现它很像翻硬币问题。。。下面引用翻硬币问题:
翻硬币问题:
硬币翻转问题是指n个硬币正面朝上放在桌子上,每次翻转m个硬币,问最少经过几次翻转可以使这n个硬币全部反面朝上。(n>m)
解决这个问题需要考虑n-m的奇偶……
1.如果n-m为偶数,那n一定可以分解成a*m+2*i的形式。。。我们先考虑m+2,m的情况,那我们通过一次翻转可以得到例0000011(n=7,m=5)这种形式。。。接着我们便可以两次借助m-1个0使最后两个1翻转过来。。那2*m+2,m+2+2,m+2+2+2,a*m+2*i便也可以多次借用m-1个0将最后的1翻转过来。然后我们就可以得到:若n-m为偶数,我们一定可以将硬币全部翻转使反面朝上。即当n与m奇偶相同时,问题恒有解。。
2.如果n-m为奇数,那n一定可以分解成a*m+b的形式(b为奇数)那我们可以拿出一个m,这时如果m为奇数,则m+b为偶数,那n便又可以
分解成(a-1)*m+2*i的形式,则翻法同上。。此时n为偶数,m为奇数。。。如果m为偶数,我们同样拿出一个m,则m+b为奇数,那n便可以分解成(a-1)*m+2*i+1的形式,因为(a-1)*m+2*i恒有解,所以不管怎么翻都会剩下一个硬币正面朝上。此时n为奇数,m为偶数。
然后我们便可得到:若n-m为奇数,当n为偶,m为奇时,问题恒有解,当n为奇,m为偶时,问题无解,且总会有且只有一个硬币无法翻转。。。
明白了以上问题,这个题就容易多了。。。我们统计一下负数的个数,记为tot,判断一下tot与m的奇偶,如果有解,则把n个数的绝对值加起来就是答案。。。如果无解,找出n个数中绝对值最小的数,让这个数成为那个无法翻转的硬币,即在和中减掉这个数的二倍即可。。。。
注意:
1.必须在线做,要不然会超过内存限制。。
2.注意特判m==n的情况。。。

#include<iostream>
#include<cstdlib>
#include<algorithm>
using namespace std;
int n,m,t1,t2,x,nn,k,minn(1000000),cc,ccc;
long long ans,ans2;
int main()
{
cin>>n>>m;
if (m==n)
{
for (int i=1;i<=n;i++)
   {
     cin>>x;
     cc+=x;
     ccc+=-x;
   }
   cout<<max(cc,ccc);
   exit(0);
}
for (int i=1;i<=n;i++)
   {
     cin>>x;
     if (x<0)
      {
    x=-x;
    nn++;
      }
      if (minn>x) minn=x;
     ans+=x; 
        } 
if (nn%2==1&&m%2==0)
{
         ans-=2*minn;
         }
    cout<<ans;
}
<think>嗯,用户想找关于PLC控制数码管循环显示数字的梯形图编程方法或示例。首先,我需要回忆一下PLC控制数码管的基本原理。数码管通常有共阴极或共阳极种类型,PLC通过输出点控制段码位选,可能需要用到移位指令或者定时器来实现循环显示。 用户提到的是梯形图编程,所以得考虑如何用梯形图的结构来实现循环。可能需要使用定时器配合计数器,或者移位寄存器来轮流点亮不同的数码管。比如,每个定时器中断触发一次移位,改变输出的位选信号段码数据。 接下来要考虑数码管的显示方式,是静态显示还是动态扫描。动态扫描更节省输出点,适合多位显示。动态扫描需要快速切换位选,同时给出对应的段码,利用人眼视觉暂留效果。这通常需要定时中断来处理,但PLC的扫描周期可能较长,需要注意刷新频率是否足够,否则会有闪烁。 然后,段码的生成需要将数字转换为对应的七段码,比如0到9的编码。可能需要一个数据表,用MOV指令根据当前计数值传送对应的段码到输出端口。此外,循环显示可能需要计数器记录当前显示的数字,并在达到最大值后复位,比如从0到9循环。 还要考虑硬件接线,数码管的段码接在PLC的Q0.0到Q0.6,位选可能如果是单个数码管的话可能不需要位选,但如果是多个,可能需要Q1.0等作为位选信号。但用户的问题可能只是单个数字的循环显示,所以可能不需要多位选通。 然后,程序结构方面,可能需要一个时钟脉冲,比如用定时器自复位产生周期性脉冲,每个脉冲触发数字增加,并更新段码。例如,使用T37定时器,每隔1秒触发一次,INC指令增加计数器,然后通过MOV指令将对应的段码传送到输出QB0。 需要检查是否存在双线圈问题,比如如果多个条件修改同一个输出点,需要避免。但在这个例子中,可能用中间变量来存储段码,最后统一输出,避免双线圈。 另外,参考用户提供的引用,引用[3]提到三菱FX系列PLC的FROMTO指令,但用户可能用的是西门子S7-200,所以需要注意指令的不同。比如西门子可能用MOV_B指令来传送数据。 可能还需要考虑数码管的类型,如果是共阳极,段码为高电平有效,共阴极则相反。程序中段码的数据需要根据硬件连接来调整。 最后,示例梯形图的结构可能包括:启动按钮控制程序运行,定时器循环触发数字变化,计数器记录当前数字,段码转换表,以及输出段码到指定Q点。同时,循环到9后复位到0。 需要验证程序的可行性,比如定时器的时间设置是否合适,段码是否正确,是否存在信号冲突等。可能还需要考虑增加停止按钮,或者复位功能。 总之,步骤应该是:硬件接线确认,定时循环触发,数字递增,段码转换,输出控制。然后根据这些步骤构建梯形图,并给出示例。</think>### PLC控制数码管循环显示数字的编程方法 #### 1. 硬件配置与原理 - **数码管类型**:常用七段数码管(共阴极或共阳极),通过PLC输出点控制段码(a-g)公共端。 - **PLC输出分配**:假设使用西门子S7-200 PLC,Q0.0-Q0.6控制段码,Q1.0控制公共端(共阴极需低电平,共阳极需高电平)[^1]。 #### 2. 实现逻辑 1. **循环显示**:通过定时器(如T37)周期性触发数字递增。 2. **段码转换**:将十进制数字转换为对应的七段码(例如,数字0对应$0x3F$,数字1对应$0x06$)。 3. **动态扫描**:若需多位数码管显示,需采用动态扫描技术,分时点亮各数码管[^2]。 #### 3. 梯形图编程示例 ```ladder 网络1:启动控制 | I0.1(启动按钮) T37(1秒定时器) |----| |----------------(TON T37, PT=1000ms)--- 网络2:数字循环递增 | T37(完成位) C0(计数器) |----| |----------------(CTU C0, PV=9)--------- 网络3:计数器复位 | C0(当前值=9) C0(复位) |----| |----------------(RESET C0)------------- 网络4:段码转换与输出 | C0(当前值) MOV_B(段码表) |----| |----------------[MOV_B 段码表(C0), QB0]-- ``` #### 4. 段码表定义 | 数字 | 段码(共阴极) | 二进制值 | |------|----------------|----------| | 0 | 0x3F | 00111111 | | 1 | 0x06 | 00000110 | | ... | ... | ... | | 9 | 0x6F | 01101111 | #### 5. 注意事项 - **防闪烁**:动态扫描频率需大于50Hz,定时器周期建议≤20ms[^3]。 - **双线圈处理**:避免同一输出点被多段逻辑重复控制。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值