JZ DAY2总结

本文深入解析了一场算法竞赛的三道题目,包括等比数列求和、淬炼神体最优化问题及部落人数变动与方差计算。文章分享了AC代码实现,探讨了快速幂、逆元、线段树等高级算法的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

DAY3DAY3DAY3

T1T1T1

学习神技学习神技

王仙女打开了《葵花宝典》,第一页上赫然写道:欲练此功,必先学习上古神技:等比数列求和!
王仙女心想:等比数列是什么**东西?难道我的修仙之路要止步于此了吗?
还好,天无绝人之路,在宝典的第二页上,写着密密麻麻的等比数列的介绍:
等比数列为这样一个数列,它的首项为a_1,第i项为a_1*q^(i-1),其中q为此等比数列的公比。等比数列前n项的求和公式为:

聪慧过人的仙女一下子就学会了等比数列的求和,可是他发现宝典上还有M道测试题,可是这M道的n都非常的大,仙女一时间算不出来,只好打通时空隧道向未来的你求助。有现代化计算机帮助的你一定能很快的求出这M个答案的对吧?

Input
第一行一个正整数M,为询问组数
接下来M行,每行三个正整数a_1,q,n,含义如题。

Output
共M行,为M个询问的答案。答案对〖10〗^9+7取模。

Sample Input
1
2 3 3

Sample Output
26

Data Constraint
对于30%的数据,M≤1000,对于每一个询问,n≤1000
对于100%的数据,M≤[10]5M ≤ [10]^5M[10]5a1,p≤109a_1,p ≤ 10^9a1,p109n≤1018n ≤ 10^{18}n1018

本来考场一旦看到数论题基本就是放弃,顶多打个暴力。可是一看这题非常可做啊,题目非常良心的给出了等比公式的求法,那么帮我这个记不住公式的蒟蒻成功去除了这个唯一的困难。那么看到这个式子先随便举了几个例子,不难发现通过正负性的判定可以将(对于q!=1q!=1q!=1)式子变形为 Sn=a1∗(qn−1)/(q−1)S_n = a_1 * (q^n - 1) / (q - 1)Sn=a1(qn1)/(q1)。那么这就是一道快速幂,逆元的水题了。有因为模数为1e9+71e9 + 71e9+7,所以逆元可以直接用bp−2b^{p - 2}bp2来求,对于n=1n = 1n=1的情况应该就是入门水平了吧。
AC Code:

#include <cstdio>
#define ll long long
using namespace std;

const int mo = 1e9 + 7;
int m;
ll a,q,n,ans;

ll ksm(ll a,ll b,ll mod)
{
	ll res = 1;
	a %= mod;
	while (b)
	{
		if (b % 2) res = (res * a) % mod;
		b /= 2;
		a = (a * a) % mod;
	}
	return res;
}

int main()
{
	scanf("%d",&m);
	while (m --)
	{
		scanf("%lld%lld%lld",&a,&q,&n);
		if (q == 1)
		{
			printf("%lld\n",(a * (n % mo)) % mo);
			continue;
		}
		ans = (a * (ksm(q,n,mo) - 1)) % mo;
		ans = (ans * (ksm(q - 1,mo - 2,mo))) % mo;
		printf("%lld\n",ans);
	}
	return 0;
}

T2T2T2

淬炼神体淬炼神体

王仙女将你提供的答案填在《葵花宝典》上,突然,宝典发出耀眼的白光,一股强大的吸力瞬间将仙女吸入宝典中。
一阵眩晕过后,仙女发现自己来到了一个浮岛上,四周的半空中也有许多大小不一的浮岛,他抬头一看,空中浮现着这样一句话:欲要成神,必先成就神体。每座浮岛都有一定的淬炼肉体的功效,但你只能选择恰好K座来淬炼你的肉体。最终你的神体有多强,就看你的造化了。
仙女看了看手中的宝典,发现上面浮现着这些浮岛的信息,每座浮岛上有两个数字。仙女研究了一会儿终于明白了,原来,每来到一座浮岛,你就会由这座岛上的神雷淬炼肉体,得到a点淬炼值,但是这种淬炼方法对身体又有一定的伤害,于是你会受到b点损伤值。而最后你的神体强度恰好为你得到的淬炼值之和与你受到的损伤值之和的比值。即神体强度=(∑a)/(∑b)。同时,你不能选择一座浮岛两次。你不必担心仙女如何到达其它的岛,宝典拥有将他传送至任何一座岛的能力。
现在,仙女想知道,他有可能淬炼出的神体的最大强度是多少。他把这个问题交给了未来的你作为刚刚帮助过他的答谢。

Input
第一行包含两个整数N,K,分别表示浮岛的数量(不包括仙女所在的浮岛)和仙女可以选择的浮岛数,浮岛的编号为1~N
第二行包含N个整数,第i个数为编号为i的浮岛的淬炼值a
第二行包含N个整数,第i个数为编号为i的浮岛的损伤值b

Output
一个实数,为仙女有可能淬炼出的神体的最大强度,保留三位小数。

Sample Input
3 2
5 7 1
4 3 2

Sample Output
1.714

Data Constraint
对于30%的数据,2≤K≤N≤10,1≤a,b≤5
对于100%的数据,2≤K≤N≤100000,1≤a,b≤1000

对于我这样一个蒟蒻,感觉考场这题没想到正解真的是非常遗憾啊,我直接打了一个正确性错误的暴力上去,即按照ai/bia_i / b_iai/bi从大到小排序,然后直接取前K大,那么错误的方法,我都做好了暴零的打算,可是竟然侥幸得到了20pts,真的是非常幸运啊。

考后一看题解,这是何等水题。首先二分枚举答案,and then因为最后判定的是∑i=1kai/∑i=1kbi&gt;=mid\sum\limits^{k}_{i = 1}a_i / \sum\limits^{k}_{i = 1}b_i &gt;= midi=1kai/i=1kbi>=mid,所以可以转换一下就变成了∑i=1kai−∑i=1kbi∗mid&gt;=0\sum\limits^{k}_{i = 1}a_i - \sum\limits^{k}_{i = 1}b_i * mid &gt;= 0i=1kaii=1kbimid>=0那么就直接按照ai−bi∗mida_i - b_i * midaibimid 排序,然后取前kkk大相加,判断是否大于零即可。

AC Code

#include <cstdio>
#include <algorithm>
using namespace std;

const int maxn = 1e5 + 10;
int n,k;
struct Node{
	double a,b,now;
} v[maxn];
double l,r,mid; 

bool cmp(Node a,Node b) {return a.now > b.now;}

bool check(double x)
{
	double res = 0;
	for (int i = 1; i <= n; i ++) v[i].now = v[i].a - x * v[i].b;
	sort(v + 1,v + 1 + n,cmp);
	for (int i = 1; i <= k ; i ++) res += v[i].now;
	if (res >= 0) return 1; else return 0;
}

int main()
{
	scanf("%d%d",&n,&k);
	for (int i = 1; i <= n; i ++) scanf("%lf",&v[i].a);
	for (int i = 1; i <= n; i ++)
	{
		scanf("%lf",&v[i].b);	
		if (v[i].a / v[i].b > r) r = v[i].a / v[i].b;
	}
	l = 0;
	while (r - l > 0.0001)
	{
		double mid = (l + r) / 2;
		if (check(mid)) l = mid + 0.0001; else r = mid;
	}
	printf("%.3lf",l);
	return 0;
}

T3T3T3

寻找神格寻找神格

淬炼完神体,王仙女被传送到了遥远处一座没有神雷的浮岛上,发现浮岛上除了一扇门以外什么都没有。他来到门前,发现上面写着这样一段话:
一个神出了拥有强大的神体外,还需要一枚神格。然而,想要获得神格没那么简单,除了有实力外还需要有运气。曾经有一个人叫金(jin)字(zi)塔(da),他的神体很强,很壮,可是他根本没有运气,所以最后神格拒绝了他。打开这扇门,你将会进入一个神格创造的空间,在那里,神格将会问你一些问题来测试你解决问题的能力,当然,它的问题将会很难,在你答不出来的时候你可以选择随便猜一个答案,以此来展现你的运气。
王仙女二话不说打开了那扇门,一阵眩晕过后,他来到了一个灰蒙蒙的空间。一个苍老的声音在四周响起:小娃娃,我是一枚存在亿万年的神格,我的上一任主人已经死去百万余年了,我也已经在这里等待了百万年了。能否成为我的主人,让我重现百万年前的风采,就看你的能力和运气了。再问问题之前,我要先跟你讲一件事。成为一个神后,最大的责任便是保护神界的人民,他们都出生在神界,但并不都具有神的实力。当然,神界人族的内部也有战争,他们一共分为N个部落,每两个部落之间都有可能发生战争。为了不然神界人族因为战争而损失惨重,神界的诸神将这些部落编号为1~N,当这些部落的人数差距太大时,诸神便会降临,将一些部落的人带走,并放一些在别的部落中。而衡量所有部落人数差距的数值便是方差。接下来,我会告诉你一些部落的人数增加或减少的信息,并会不时的询问你编号为L ~ R的部落的总人数或是他们部落人数的方差。

Input
第一行包含两个正整数N,Q,表示部落数和神格的信息数与询问数总和。
第二行包含N个数,第i个数a_i表示编号为i的部落最初的人数。
接下来Q行,第一个数为t。
当t=0时,这一行还有两个数a,b,表示编号为a的部落增加了b个人(如果b<0则表示减少了|b|个人)。
当t=1时,这一行还有三个数a,b,c,表示编号为a~b的部落增加了c个人(如果c<0则表示减少了|c|个人)。
当t=2时,这一行还有两个数a,b,表示神格询问了编号为a~b的部落现在的总人数。
当t=3时,这一行还有两个数a,b,表示神格询问了编号为a~b的部落人数的方差。

Output
对于每个t=2,输出一行,包含一个整数,表示总人数。
对于每个t=3,输出一行,包含一个实数,表示方差,结果保留三位小数。

Sample Input
5 5
1 2 3 4 5
0 3 3
1 2 3 6
2 3 5
0 1 2
3 1 5

Sample Output
21
10.640

Data Constraint
对于30%的数据,N≤1000,Q≤1000
对于100%的数据,1≤N≤100000,1≤Q≤100000,|a_i |≤1000,数据保证在任何时候|所有部落总人数|≤〖10〗^9
注:由于神界人族的人数统计是用实际人数减去一个标准值,所以人数可能会出现负数

Hint
方差的定义:
NNN个数的方差,设这NNN个数的平均数为aveaveave,第i个数为xix_ixi
方差S=1/n [(x1−ave)2+(x2−ave)2+⋯+(xn−1−ave)2+(xn−ave)2]S=1/n \ [(x_1-ave)^2+(x_2-ave)^2+⋯+(x_{n-1}-ave)^2+(x_n-ave)^2]S=1/n [(x1ave)2+(x2ave)2++(xn1ave)2+(xnave)2]

考场当我打到这道题是仅剩303030min,一看,这不是线段树吗,没管三七二十一,啪啪啪就花十五分钟把方差以前的线段树内容全部都敲上了,打到方差的那个瞬间忽然懵比,其实假如我往下推大概也就三分钟就可以推出来了,可是时间不允许我这样做啊,我就用剩下的十分钟干脆打了个暴力交了,考试毕竟拿分重要。最后也拿了20pts。

赛后,自己推了一下,其实很简单。首先是拆开求方差的公式
S=1/n [(x1−ave)2+(x2−ave)2+⋯+(xn−1−ave)2+(xn−ave)2]=1/n [x12+ave2−2∗ave∗x1+x22+ave2−2∗ave∗x2+⋯+xn−12+ave2−2∗ave∗xn−1+xn2+ave2−2∗ave∗xn]=1/n [x12+x22+⋯+xn−12+xn2+n∗ave2−2ave∗∑i=LRxi]S = 1/n \ [(x_1-ave)^2+(x_2-ave)^2+⋯+(x_{n-1}-ave)^2+(x_n-ave)^2] \\\\\\\\\\\\\\= 1 / n \ [x_1^2 + ave^2 - 2*ave*x_1 + x_2^2 + ave^2 - 2*ave*x_2 + ⋯ + x_{n - 1}^2 + ave^2 - 2*ave*x_{n - 1} +x_n^2 + ave^2 - 2*ave*x_n] \\\\\\\\\\\\= 1 / n \ [x_1^2 +x_2^2 + ⋯ +x_{n - 1}^2 + x_n^2 + n * ave^2 - 2ave * \sum\limits^{R}_{i = L} x_i]S=1/n [(x1ave)2+(x2ave)2++(xn1ave)2+(xnave)2]=1/n [x12+ave22avex1+x22+ave22avex2++xn12+ave22avexn1+xn2+ave22avexn]=1/n [x12+x22++xn12+xn2+nave22avei=LRxi],那么接下来我们在普通线段树的基础上需要做的仅仅是多维护一个平方和,至于平方和其实也并不难,只要我们心平气和地稍作思考。
首先随便举了几个例子,不难发现对于一定的sumsumsum,加上或减去一个数对该平方和的影响是一定的。且很容易推出,当加一个kkk时,对于平方和的影响为(x1+k)2+(x2+k)2+⋯+(xn−1+k)2+(xn+k)2(x_1 + k)^2 + (x_2 + k)^2 + ⋯ +(x_{n - 1} + k)^2 +(x_n + k)^2(x1+k)2+(x2+k)2++(xn1+k)2+(xn+k)2,and then 拆开得
x12+k2+2∗k∗x1+x22+k2+2∗k∗x2+⋯+xn−12+k2+2∗k∗xn−1+xn2+k2+2∗k∗knx_1^2 + k^2 + 2 * k * x_1 + x_2^2 + k ^ 2 + 2 * k * x_2 + ⋯ + x_{n - 1} ^ 2 + k ^ 2 + 2 * k * x_{n - 1} + x_n^2 + k^2 + 2 * k *k_nx12+k2+2kx1+x22+k2+2kx2++xn12+k2+2kxn1+xn2+k2+2kkn
再合并得
∑i=1nxi2+2∗k∗∑i=LRxi+n∗k2\sum\limits^{n}_{i = 1} x_i^2 + 2 * k * \sum\limits^{R}_{i = L} x_i + n * k^2i=1nxi2+2ki=LRxi+nk2。终于功德圆满了,上代码。
AC Code

#include <cstdio>
#include <algorithm>
#define ll long long
using namespace std;

const int maxn = 1e5 + 10;
int n,q,v[maxn],p,a,b,c;
ll t[maxn * 50],s[maxn * 50],tag[maxn * 50];
double u,ans,ba;

int read()
{
	int x = 0,w = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9') {if (ch == '-') w = -1;ch = getchar();}
	while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}
	return x * w;
}

void build(int x,int l,int r)
{
	if (l == r) {t[x] = 1ll * v[l]; s[x] = 1ll * v[l] * v[l]; return;}
	int mid = (l + r) >> 1;
	build(x << 1,l,mid);
	build(x << 1 | 1,mid + 1,r);
	t[x] = t[x << 1] + t[x << 1 | 1];
	s[x] = s[x << 1] + s[x << 1 | 1];
}

void down(int x,int l,int r)
{
	int mid = (l + r) >> 1;
	tag[x << 1] += tag[x];
	tag[x << 1 | 1] += tag[x];
	s[x << 1] += 2 * tag[x] * t[x << 1] + 1ll * (mid - l + 1) * tag[x] * tag[x];
	s[x << 1 | 1] += 2 * tag[x] * t[x << 1 | 1] + 1ll * (r - mid) * tag[x] * tag[x];
	t[x << 1] += tag[x] * 1ll * (mid - l + 1);
	t[x << 1 | 1] += tag[x] * 1ll * (r - mid);
	tag[x] = 0;
}

void update(int x,int l,int r,int L,int R,int k)
{
	if (L <= l && R >= r)
	{
		tag[x] += 1ll * k;
		s[x] += 1ll * 2 * k * t[x] + 1ll * (r - l + 1) * k * k;
		t[x] += 1ll * k * (r - l + 1);
		return;
	}
	if (tag[x]) down(x,l,r);
	int mid = (l + r) >> 1;
	if (L <= mid) update(x << 1,l,mid,L,R,k);
	if (R > mid) update(x << 1 | 1,mid + 1,r,L,R,k);
	t[x] = t[x << 1] + t[x << 1 | 1];
	s[x] = s[x << 1] + s[x << 1 | 1];
}

ll query(int x,int l,int r,int L,int R)
{
	if (L <= l && R >= r) return t[x];
	ll res = 0;
	int mid = (l + r) >> 1;
	if (tag[x]) down(x,l,r);
	if (L <= mid) res += query(x << 1,l,mid,L,R);
	if (R > mid) res += query(x << 1 | 1,mid + 1,r,L,R);
	return res;
}

ll querys(int x,int l,int r,int L,int R)
{
	if (L <= l && R >= r) return s[x];
	ll res = 0;
	int mid = (l + r) >> 1;
	if (tag[x]) down(x,l,r);
	if (L <= mid) res += querys(x << 1,l,mid,L,R);
	if (R > mid) res += querys(x << 1 | 1,mid + 1,r,L,R);
	return res;
}

int main()
{
	n = read(),q = read();
	for (int i = 1; i <= n; i ++) v[i] = read();
	build(1,1,n);
	while (q --)
	{
		p = read();
		if (p == 0) 
		{
			a = read(),b = read();
			update(1,1,n,a,a,b);
		}
		if (p == 1)
		{
			a = read(),b = read(),c = read();
			update(1,1,n,a,b,c);
		}
		if (p == 2)
		{
			a = read(),b = read();
			printf("%lld\n",query(1,1,n,a,b));
		}
		if (p == 3)
		{
			a = read(),b = read();
			ans = 0;
			u = 1.000 * query(1,1,n,a,b);;
			ba = u / (b - a + 1);
			ans = querys(1,1,n,a,b) + (b - a + 1) * ba * ba - 2 * ba * u;
			ans /= (b - a + 1);
			printf("%.10lf\n",ans);
		}
	}
	return 0;
}

此处还有一个非常神奇的坑点,便是精度问题,最后要取十位小数。
最终得分100+20+20100 + 20 + 20100+20+20,排名也还算客观。

Ps.经过几篇博客的磨练,感觉格式好看多了,继续加油。

; C51???????? ; ????: ; LCD??? = P0 ; LCD???: RS=P2.0, RW=P2.1, EN=P2.2 ; ??: SET=P3.0, INC=P3.1, DEC=P3.2, MODE=P3.3 ; ??RAM?? SECOND EQU 30H ; ? MINUTE EQU 31H ; ? HOUR EQU 32H ; ? DAY EQU 33H ; ? MONTH EQU 34H ; ? YEAR EQU 35H ; ? WEEKDAY EQU 36H ; ??(0=??,1=??...6=??) ALARM_H EQU 37H ; ??? ALARM_M EQU 38H ; ??? MODE_FLAG EQU 39H ; ????(0=??,1=????,2=????,3=????) CURSOR EQU 3AH ; ?????? TICK_CNT EQU 3BH ; 50ms?? SEC_FLAG EQU 3CH ; ???? ORG 0000H LJMP MAIN ORG 000BH ; ???0???? LJMP TIMER0_ISR MAIN: MOV SP, #60H ; ?????? LCALL INIT_VARS ; ????? LCALL LCD_INIT ; ???LCD LCALL TIMER_INIT ; ?????? MAIN_LOOP: LCALL KEY_SCAN ; ???? LCALL DISPLAY_TIME ; ???? LCALL CHECK_ALARM ; ???? SJMP MAIN_LOOP ; ????? INIT_VARS: MOV SECOND, #00H ; ???? 00:00:00 MOV MINUTE, #00H MOV HOUR, #00H MOV DAY, #01H ; ???? 01/01/00 MOV MONTH, #01H MOV YEAR, #00H MOV WEEKDAY, #01H ; ?? MOV ALARM_H, #07H ; ??07:00 MOV ALARM_M, #00H MOV MODE_FLAG, #00H MOV CURSOR, #00H MOV TICK_CNT, #00H MOV SEC_FLAG, #00H RET ; ?????? TIMER_INIT: MOV TMOD, #01H ; ???0??1 MOV TH0, #3CH ; 50ms??(11.0592MHz) MOV TL0, #0B0H SETB TR0 ; ????? SETB ET0 ; ??????? SETB EA ; ???? RET ; ???0?????? TIMER0_ISR: PUSH ACC MOV TH0, #3CH ; ???? MOV TL0, #0B0H INC TICK_CNT MOV A, TICK_CNT CJNE A, #20, TIMER_EXIT ; 50ms*20=1s MOV TICK_CNT, #00H SETB SEC_FLAG ; ????? ; ???? INC SECOND MOV A, SECOND CJNE A, #60, TIMER_EXIT MOV SECOND, #00H INC MINUTE MOV A, MINUTE CJNE A, #60, TIMER_EXIT MOV MINUTE, #00H INC HOUR MOV A, HOUR CJNE A, #24, TIMER_EXIT MOV HOUR, #00H ; ??????? INC DAY INC WEEKDAY MOV A, WEEKDAY CJNE A, #7, CHECK_DAY MOV WEEKDAY, #0 CHECK_DAY: MOV A, MONTH CJNE A, #2, NOT_FEB ; ??2? MOV A, YEAR ANL A, #03H ; ??????(??4??) JNZ FEB_28 MOV A, DAY CJNE A, #30, TIMER_EXIT SJMP MONTH_END FEB_28: MOV A, DAY CJNE A, #29, TIMER_EXIT SJMP MONTH_END NOT_FEB: MOV A, MONTH CJNE A, #4, CHECK_30 SJMP CHECK_31 CHECK_30: CJNE A, #6, CHECK_31 SJMP CHECK_31 ; 30??? MOV A, DAY CJNE A, #31, TIMER_EXIT SJMP MONTH_END CHECK_31: ; 31??? MOV A, DAY CJNE A, #32, TIMER_EXIT MONTH_END: MOV DAY, #01H INC MONTH MOV A, MONTH CJNE A, #13, TIMER_EXIT MOV MONTH, #01H INC YEAR MOV A, YEAR CJNE A, #100, TIMER_EXIT MOV YEAR, #00H TIMER_EXIT: POP ACC RETI ; LCD??? LCD_INIT: LCALL DELAY ; ??LCD???? MOV A, #38H ; 8???,2???,5x7?? LCALL LCD_CMD MOV A, #0CH ; ???,??? LCALL LCD_CMD MOV A, #06H ; ????,??? LCALL LCD_CMD MOV A, #01H ; ?? LCALL LCD_CMD RET ; LCD?????? LCD_CMD: MOV P0, A ; ????P0 CLR P2.0 ; RS=0(??) CLR P2.1 ; RW=0(?) SETB P2.2 ; EN=1 LCALL DELAY ; ??? CLR P2.2 ; EN=0 LCALL DELAY RET ; LCD?????? LCD_DATA: MOV P0, A ; ????P0 SETB P2.0 ; RS=1(??) CLR P2.1 ; RW=0(?) SETB P2.2 ; EN=1 LCALL DELAY ; ??? CLR P2.2 ; EN=0 LCALL DELAY RET ; ?????? DISPLAY_TIME: MOV A, #80H ; ??????? LCALL LCD_CMD ; ???? HH:MM:SS MOV A, HOUR LCALL DISP_BCD MOV A, #':' ; ???? LCALL LCD_DATA MOV A, MINUTE LCALL DISP_BCD MOV A, #':' LCALL LCD_DATA MOV A, SECOND LCALL DISP_BCD ; ???? YY/MM/DD MOV A, #0C0H ; ??????? LCALL LCD_CMD MOV A, YEAR LCALL DISP_BCD MOV A, #'/' LCALL LCD_DATA MOV A, MONTH LCALL DISP_BCD MOV A, #'/' LCALL LCD_DATA MOV A, DAY LCALL DISP_BCD ; ???? MOV A, #0CAH ; ????11? LCALL LCD_CMD MOV A, WEEKDAY ADD A, #'0' ; ???ASCII LCALL LCD_DATA ; ?????? MOV A, #8FH ; ????? LCALL LCD_CMD MOV A, #'A' ; ??A?????? LCALL LCD_DATA RET ; ??BCD?(????) DISP_BCD: MOV R0, A SWAP A ; ????? ANL A, #0FH ADD A, #'0' LCALL LCD_DATA MOV A, R0 ; ????? ANL A, #0FH ADD A, #'0' LCALL LCD_DATA RET ; ???? KEY_SCAN: JB P3.0, KEY_INC ; SET???? LCALL DELAY_10MS JB P3.0, KEY_INC JNB P3.0, $ ; ???? ; ???? MOV A, MODE_FLAG INC A CJNE A, #4, SET_MODE MOV A, #0 SET_MODE: MOV MODE_FLAG, A MOV CURSOR, #0 ; ?????? RET KEY_INC: JB P3.1, KEY_DEC ; INC???? LCALL DELAY_10MS JB P3.1, KEY_DEC JNB P3.1, $ ; ???? ; ????????? MOV A, MODE_FLAG JZ KEY_EXIT ; ??????? ; ?????? CJNE A, #1, CHK_DATE LCALL INC_TIME RET CHK_DATE: CJNE A, #2, CHK_ALARM LCALL INC_DATE RET CHK_ALARM: CJNE A, #3, KEY_EXIT LCALL INC_ALARM RET KEY_DEC: JB P3.2, KEY_MODE ; DEC???? LCALL DELAY_10MS JB P3.2, KEY_MODE JNB P3.2, $ ; ???? ; ????????? MOV A, MODE_FLAG JZ KEY_EXIT ; ?????? CJNE A, #1, DEC_DATE LCALL DEC_TIME RET DEC_DATE: CJNE A, #2, DEC_ALARM LCALL DEC_DATE RET DEC_ALARM: CJNE A, #3, KEY_EXIT LCALL DEC_ALARM RET KEY_MODE: JB P3.3, KEY_EXIT ; MODE?(?????) LCALL DELAY_10MS JB P3.3, KEY_EXIT JNB P3.3, $ ; ???? MOV A, MODE_FLAG JZ KEY_EXIT ; ??????? ; ?????????? INC CURSOR MOV A, CURSOR CJNE A, #3, KEY_EXIT ; ??/???3? MOV CURSOR, #0 KEY_EXIT: RET ; ????? INC_TIME: MOV A, CURSOR JZ INC_HOUR CJNE A, #1, INC_SEC ; ???? INC MINUTE MOV A, MINUTE CJNE A, #60, INC_EXIT MOV MINUTE, #0 RET INC_HOUR: INC HOUR MOV A, HOUR CJNE A, #24, INC_EXIT MOV HOUR, #0 RET INC_SEC: INC SECOND MOV A, SECOND CJNE A, #60, INC_EXIT MOV SECOND, #0 INC_EXIT: RET ; ????? INC_DATE: MOV A, CURSOR JZ INC_YEAR CJNE A, #1, INC_DAY ; ???? INC MONTH MOV A, MONTH CJNE A, #13, INC_EXIT MOV MONTH, #1 RET INC_YEAR: INC YEAR MOV A, YEAR CJNE A, #100, INC_EXIT MOV YEAR, #0 RET INC_DAY: INC DAY MOV A, DAY CJNE A, #32, INC_EXIT MOV DAY, #1 RET ; ????? INC_ALARM: MOV A, CURSOR JZ INC_ALARM_H ; ???? INC ALARM_M MOV A, ALARM_M CJNE A, #60, INC_EXIT MOV ALARM_M, #0 RET INC_ALARM_H: INC ALARM_H MOV A, ALARM_H CJNE A, #24, INC_EXIT MOV ALARM_H, #0 RET ; ?????(??????,?) DEC_TIME: ; ????INC_TIME???? RET ; ???? CHECK_ALARM: MOV A, HOUR CJNE A, ALARM_H, ALARM_EXIT MOV A, MINUTE CJNE A, ALARM_M, ALARM_EXIT ; ????(?????LED??) CPL P1.7 ; ??P1.7??LED ALARM_EXIT: RET ; ????? DELAY: MOV R6, #50 DL1: MOV R7, #200 DL2: DJNZ R7, DL2 DJNZ R6, DL1 RET DELAY_10MS: MOV R5, #20 DL3: MOV R6, #250 DL4: DJNZ R6, DL4 DJNZ R5, DL3 RET END 这段代码烧录后9到0时出现;=?>等符号,且减法无用,修改代码
最新发布
07-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值