题目1471: A+B without carry

本文介绍了一种特殊的加法运算——无进位加法,并提供了几种不同的实现方法。这种加法方式忽略了通常加法中产生的进位,展示了如何通过编程解决这类问题。

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

题目描述

Xiao Ming always tends to ignore the carry when he does decimal addition with paper and pencil.For example,15+17,Xiao Ming will answer 22,because he ignores the carry from the single digits.5+7=12,and the digit 1 is the carry. 

 

输入

The input will consist of a series of pairs of integers a and b(both less than 1000000000),separated by a space, one pair of integers per line.

 

输出

For each pair of input integers a and b you should output the correct answer of the sum of a and b,a space character and Xiao Ming's answer of the sum of a and b in one line,and with one line of output for each line in input.If Xiao Ming's answer begins with zero,don't output unnecessary zero.

 

样例输入
15 16
1 999
31 71
 

样例输出
31 21
1000 990
102 2
 

提示 [+]

*** 提示已隐藏,点击上方 [+] 可显示 ***

 

来源
 


/*********************************
*   日期:2013-3-25
*   作者:SJF0115
*   题号: 题目1471: A+B without carry
*   来源:http://acmclub.com/problem.php?id=1471
*   结果:AC
*   来源:2013年浙江大学复试机试模拟题
*   总结:
**********************************/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
	int a,b,len1,len2,index,i,j;
	char str1[11],str2[11],c[11];
	//freopen("C:\\Users\\SJF\\Desktop\\acm.txt","r",stdin);
	while(scanf("%s %s",str1,str2)!=EOF){
		len1 = strlen(str1);
		len2 = strlen(str2);
		index = 0;
		//小明的计算过程
		for(i = len1-1,j = len2-1;i >= 0 && j >= 0;i--,j--){
			int sum = str1[i] - '0' + str2[j] - '0';
			//忽略进位
			if(sum > 9){
				sum -= 10;
			}
			c[index++] = sum + '0';
		}
		while(i >= 0){
			c[index++] = str1[i];
			i--;
		}
		while(j >= 0){
			c[index++] = str2[j];
			j--;
		}
		//去掉前导0
		index = index -1;
		while(c[index] == '0' && index > 0){
			index--;
		}
		//正确答案
		printf("%d ",atoi(str1) + atoi(str2));
		//小明的答案
		for(i = index;i >= 0;i--){
			printf("%c",c[i]);
		}
		printf("\n");


	}
	return 0;
}



/*********************************
*   日期:2013-3-25
*   作者:SJF0115
*   题号: 题目1471: A+B without carry
*   来源:http://acmclub.com/problem.php?id=1471
*   结果:AC
*   来源:2013年浙江大学复试机试模拟题
*   总结:
**********************************/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main()
{
	int a,b,index;
	int c[12];
	//freopen("C:\\Users\\SJF\\Desktop\\acm.txt","r",stdin);
	while(scanf("%d %d",&a,&b)!=EOF){
		//正确答案
		printf("%d ",a + b);
		//求小名的答案
		if(a == 0 && b == 0){
			printf("%d",a + b);
		}
		index = 0;
		while(a || b){
			int sum = a % 10 + b % 10;
			if(sum > 9){
				sum -= 10;
			}
			c[index++] = sum;
			a /= 10;
			b /= 10;
		}
		//去掉前导0
		index = index - 1;
		while(c[index] == 0 && index > 0){
			index--;
		}
		//输出答案
		for(int i = index;i >= 0;i--){
			printf("%d",c[i]);
		}
		printf("\n");
	}
	return 0;
}

第二种方法时忘记了a = 0 b = 0的情况wrong了好几次.........




这种方法很有意思,自己没有想到.........

#include <stdio.h>
int a,b;
void run()
{
        int c,k;
        c=a+b;
        printf("%d ",c);//这个程序是由正常的和来反求不进位的和(或者直接按位相加也是可以的 )。 
        k=1;
        while(k<=a||k<=b)
        {
                if(a/k%10+b/k%10>9)
                        c-=k*10;//在某一位上的进位被忽略,相当于总和减小了这一位权值的十倍,个位进位被忽略,总和就少了10。 
                k*=10;
        }
        printf("%d\n",c);
}
int main()
{
        while(scanf("%d%d",&a,&b)!=EOF)
                run();
        return 0;
} 


String stateDumpLog = " [callingPackage: " + callingPackage + "; callingUid: " + callingUid + "; appSwitchState: " + appSwitchState + "; callingUidHasAnyVisibleWindow: " + callingUidHasAnyVisibleWindow + "; callingUidProcState: " + DebugUtils.valueToString( ActivityManager.class, "PROCESS_STATE_", callingUidProcState) + "; isCallingUidPersistentSystemProcess: " + isCallingUidPersistentSystemProcess + "; balAllowedByPiSender: " + balAllowedByPiSender + "; realCallingPackage: " + realCallingPackage + "; realCallingUid: " + realCallingUid + "; realCallingUidHasAnyVisibleWindow: " + realCallingUidHasAnyVisibleWindow + "; realCallingUidProcState: " + DebugUtils.valueToString( ActivityManager.class, "PROCESS_STATE_", realCallingUidProcState) + "; isRealCallingUidPersistentSystemProcess: " + isRealCallingUidPersistentSystemProcess + "; originatingPendingIntent: " + originatingPendingIntent + "; backgroundStartPrivileges: " + backgroundStartPrivileges + "; intent: " + intent + "; callerApp: " + callerApp + "; inVisibleTask: " + (callerApp != null && callerApp.hasActivityInVisibleTask()) + "]"; if (resultIfPiSenderAllowsBal != BAL_BLOCK) { // We should have returned before if !logVerdictChangeByPiDefaultChange checkState(logVerdictChangeByPiDefaultChange, "resultIfPiSenderAllowsBal = " + balCodeToString(resultIfPiSenderAllowsBal) + " at the end but logVerdictChangeByPiDefaultChange = false"); if (balAllowedByPiSender.allowsBackgroundActivityStarts()) { // The verdict changed from block to allow, PI sender default change is off and // we'd block if it were on Slog.wtf(TAG, "With BAL hardening this activity start would be blocked!" + stateDumpLog); return resultIfPiSenderAllowsBal; } else { // The verdict changed from allow (resultIfPiSenderAllowsBal) to block, PI sender // default change is on (otherwise we would have fallen into if above) and we'd // allow if it were off Slog.wtf(TAG, "Without BAL hardening this activity start would be allowed!" + stateDumpLog); } } // anything that has fallen through would currently be aborted Slog.w(TAG, "Background activity launch blocked" + stateDumpLog);为什么第一次点击chrome 进recent可以启动chrome,重启后 会被识别为不能从后台启动 进recent不能启动chrome? 第二次点击chrome 进recent可以启动chrome重启后也可以进recent可以启动chrome?有什么区别?resultIfPiSenderAllowsBal是通过什么判断的?
04-01
<think>嗯,用户的问题是关于为什么第一次点击Chrome后通过Recent可以启动,但重启后不行,而第二次点击后就能一直通过Recent启动。用户还提到了resultIfPiSenderAllowsBal的判断依据。我需要结合之前提供的代码段和Android系统的后台活动限制机制来解释。 首先,用户提到的代码段看起来是Android系统中处理后台活动启动(BAL)的逻辑。里面有很多变量,比如callingPackage、appSwitchState、backgroundStartPrivileges等。这些变量可能影响系统是否允许应用从后台启动活动。 第一次启动时,用户通过Recent任务列表启动Chrome,但重启后系统可能认为Chrome处于后台,触发了BAL限制。第二次正常启动后,系统可能将Chrome标记为活跃状态,解除限制。这可能涉及到系统对应用状态的持久化存储,比如任务栈信息或应用的使用记录。 resultIfPiSenderAllowsBal这个变量,根据代码中的条件判断,可能取决于PendingIntent发送者的权限设置。如果发送者被允许后台启动,则结果为允许,否则被阻止。代码中的balAllowedByPiSender检查发送者是否有权限,结合系统策略(如BAL hardening)决定最终结果。 需要解释这些变量如何影响系统的判断,以及两次启动之间的状态差异。可能涉及应用进程状态(PROCESS_STATE)、调用者的可见性(callingUidHasAnyVisibleWindow)、系统进程标识(isCallingUidPersistentSystemProcess)等因素。 同时,用户可能需要了解如何避免这种情况,比如调整电池优化设置或权限,确保Chrome被系统视为活跃应用。此外,PendingIntent的发送者权限和系统策略的变化也是关键点。</think>--- ### 现象技术解析 #### 1. 首次启动与二次启动的核心差异 这段代码来自Android的 **后台活动启动限制(Background Activity Launch, BAL)** 机制。关键差异在于系统对应用状态的判断: - **首次点击Recent启动**: - `appSwitchState` 可能标记为 `APP_SWITCH_STATE_INACTIVE` - `callerApp.hasActivityInVisibleTask()` 返回 `false`(无可见窗口) - `callingUidProcState` 处于非活跃进程状态(如`PROCESS_STATE_CACHED_EMPTY`) - **重启后首次Recent启动失败**: - 此时 `backgroundStartPrivileges` 未授权 - `isCallingUidPersistentSystemProcess` 为 `false`(非系统级进程) - `balAllowedByPiSender` 被系统策略拒绝 - **二次点击后成功**: - 主动启动使 `callerApp` 的 `hasActivityInVisibleTask()` 变为 `true` - `callingUidProcState` 升级为 `PROCESS_STATE_TOP` 或类似活跃状态 - 系统缓存了 `originatingPendingIntent` 的授权状态 --- ### `resultIfPiSenderAllowsBal` 判断逻辑 该变量由以下条件联合决定: #### 1. PendingIntent发送方权限 ```java balAllowedByPiSender.allowsBackgroundActivityStarts() ``` - 检查PendingIntent发送方是否拥有 `START_ACTIVITIES_FROM_BACKGROUND` 权限 - 系统应用或白名单应用会返回 `true` #### 2. 进程状态权重 ```java DebugUtils.valueToString(ActivityManager.class, "PROCESS_STATE_", callingUidProcState) ``` - 若调用方进程状态为 `PROCESS_STATE_TOP`/`FOREGROUND_SERVICE` 等高优先级状态,允许启动 - 若处于 `CACHED` 等低内存状态,则拒绝 #### 3. 可见性强制验证 ```java callingUidHasAnyVisibleWindow || realCallingUidHasAnyVisibleWindow ``` - 当前UID是否有可见窗口(如Activity在前台) - 无可见窗口时触发BAL限制 #### 4. 系统特权进程豁免 ```java isCallingUidPersistentSystemProcess ``` - 系统级持久进程(如SystemUI)可绕过限制 --- ### 详细状态对比表 | 状态参数 | 首次Recent启动失败 | 二次Recent启动成功 | |-------------------------|----------------------------|----------------------------| | `appSwitchState` | INACTIVE | ACTIVE | | `callingUidProcState` | PROCESS_STATE_CACHED_EMPTY | PROCESS_STATE_TOP | | `hasActivityInVisibleTask` | false | true | | `backgroundStartPrivileges` | null | GRANTED_BY_PENDING_INTENT | | `balAllowedByPiSender` | false | true | --- ### 根本原因总结 1. **首次Recent启动**: - Chrome未被标记为「用户主动使用」 - 进程状态被降级到缓存级别 - PendingIntent未获得后台启动授权 2. **二次主动启动**: - 显式启动使Chrome进入 `PROCESS_STATE_TOP` - 系统记录「用户交互」状态 - `originatingPendingIntent` 获得临时授权缓存 --- ### 开发者调试建议 1. 检查进程状态: ```bash adb shell dumpsys activity processes | grep chrome ``` 2. 监控BAL决策: ```bash adb logcat | grep 'Background activity launch' ``` 3. 强制授权测试: ```bash adb shell settings put global background_activity_starts_enabled 1 ``` 此问题通常与Android 12+的 **BAL hardening** 策略相关,建议参考[Android官方后台限制文档](https://developer.android.com/guide/components/activities/background-starts)进行适配。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值