CF1020B Badge (#模拟 -2.4)

解决一个关于学生相互告状的问题,通过模拟过程找出最终被老师认为是主要恶作剧者的学生。采用C++编程实现。

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

Problem Description

In Summer Informatics School, if a student doesn't behave well, teachers make a hole in his badge. And today one of the teachers caught a group of n students doing yet another trick.

Let's assume that all these students are numbered from 11 to nn. The teacher came to student aa and put a hole in his badge. The student, however, claimed that the main culprit is some other student papa.

After that, the teacher came to student papa and made a hole in his badge as well. The student in reply said that the main culprit was student ppappa.

This process went on for a while, but, since the number of students was finite, eventually the teacher came to the student, who already had a hole in his badge.

After that, the teacher put a second hole in the student's badge and decided that he is done with this process, and went to the sauna.

You don't know the first student who was caught by the teacher. However, you know all the numbers pi. Your task is to find out for every student a, who would be the student with two holes in the badge if the first caught student was a.

Input

The first line of the input contains the only integer n (1≤n≤1000) — the number of the naughty students.

The second line contains n integers p1, ..., pn (1≤pi≤n), where pipi indicates the student who was reported to the teacher by student i.

Output

For every student aa from 1 to n print which student would receive two holes in the badge, if aa was the first student caught by the teacher.

输入输出样例

输入样例#1

3
2 3 2

输出样例#1

2 2 3 

输入样例#2

3
1 2 3

输出样例#2

1 2 3 

说明

The picture corresponds to the first example test case.

When a=1 , the teacher comes to students 1 , 2 , 3 , 2 , in this order, and the student 2 is the one who receives a second hole in his badge.

When a=2 , the teacher comes to students 2 , 3 , 2 , and the student 2 gets a second hole in his badge. When a=3 , the teacher will visit students 3 , 2 , 3 with student 3 getting a second hole in his badge.

For the second example test case it's clear that no matter with whom the teacher starts, that student would be the one who gets the second hole in his badge.


思路

n 个学生,每个学生都说是另一个学生做的坏事,老师从第 i 个学生的话开始向下寻找,直到第二次找到这个学生为止。

还是纯模拟。

#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
	int p[10001]={},a[10001]={};
	register int i,j;
	int n;
	cin>>n;
	for(i=1;i<=n;i++)
	{
		cin>>p[i];
	}
	for(i=1;i<=n;i++)
	{
		memset(a,0,sizeof(a));
		int t=i;;
		while(true)
		{
			a[t]++;
			t=p[t];
			if(a[t]==2)
			{
				break;
			}
		}
		cout<<t<<' ';
	}
	cout<<endl;
	return 0;
}

 

<think>我们正在处理一个Android设备上的权限问题:尝试修改`/storage/emulated`目录的权限时遇到`Permission denied`错误。根据引用[1]和[2],这是一个常见的权限问题,尤其是在某些特定机型(如三星A7100)上。引用[3]和[4]则提供了关于`chmod`命令的详细信息,但需要注意的是,在Android系统中,直接使用`chmod`修改系统目录通常需要root权限。 ### 问题分析 1. **权限模型限制**:Android的存储目录(如`/storage/emulated`)受Linux权限模型和SELinux策略保护。普通应用(包括通过ADB shell访问的非root用户)无法修改这些目录的权限。 2. **机型差异**:某些厂商(如三星)可能加强了存储访问限制,导致在相同代码和权限声明下,部分机型出现`EACCES (Permission denied)`错误(引用[1])。 3. **Android版本差异**:从Android 10(API 29)开始,Scoped Storage限制了应用对外部存储的直接访问。 ### 解决方案 #### 方法1:检查并请求正确的运行时权限(无需root) 在Android 6.0(API 23)及以上,除了在`AndroidManifest.xml`中声明权限,还需要在运行时请求权限。对于存储权限,需要请求: - `WRITE_EXTERNAL_STORAGE`(Android 9及以下) - 或使用`MANAGE_EXTERNAL_STORAGE`(Android 10及以上,但需要跳转到设置界面) **步骤**: 1. 在`AndroidManifest.xml`中声明权限: ```xml <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- 针对Android 10及以上,如果使用MANAGE_EXTERNAL_STORAGE --> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> ``` 2. 在代码中请求运行时权限(以WRITE_EXTERNAL_STORAGE为例): ```java if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE); } } ``` 3. 针对Android 10及以上,如果需要访问其他应用的文件,需使用Storage Access Framework(SAF)或申请`MANAGE_EXTERNAL_STORAGE`权限(需用户手动授权): ```java if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { if (!Environment.isExternalStorageManager()) { Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION); startActivity(intent); } } ``` #### 方法2:使用正确的文件路径(避免直接访问`/storage/emulated`) - 应用应使用系统提供的API获取外部存储路径,而不是硬编码路径。例如: ```java File downloadsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); File file = new File(downloadsDir, "abc.apk"); ``` 或 ```java File externalDir = getExternalFilesDir(null); // 获取应用私有外部存储目录 ``` 这样能确保路径在当前设备上有效,且应用有权限访问。 #### 方法3:针对特定机型的三星设备 三星设备可能对存储访问有额外限制。尝试以下操作: 1. 检查设备的“权限监控”软件(如三星的Knox)是否阻止了写入。 2. 在应用设置中手动授予存储权限:设置 → 应用 → 选择你的应用 → 权限 → 存储 → 允许。 #### 方法4:使用ADB修改权限(需root,高风险) 如果设备已root,可以通过ADB执行: ```bash adb shell su chmod -R 777 /storage/emulated ``` 但**强烈不推荐**,因为: - 递归修改整个`/storage/emulated`权限会破坏系统安全机制。 - 可能导致系统不稳定或数据泄露。 #### 方法5:针对下载APK场景的优化 在自动更新中下载APK时,建议: 1. 将APK保存到应用私有目录(无需权限): ```java File outputFile = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "update.apk"); ``` 2. 如果必须保存到公共目录(如Download),确保已获取运行时权限,并使用`MediaScannerConnection`扫描文件,使其在文件管理器中可见。 ### 总结 - **首选方案**:使用应用私有目录(无需权限)或通过运行时权限访问公共目录。 - **避免方案**:不要尝试修改系统级目录(如`/storage/emulated`)的权限,这通常需要root且风险高。 - **机型适配**:针对三星等厂商设备,检查额外权限设置。 如果问题仍然存在,请提供更多信息(如Android版本、错误日志完整内容)。 §§相关问题§§ 1. 如何在 Android 10 及以上版本中正确请求存储权限? 2. 三星设备存储权限的特殊处理方式有哪些? 3. 应用私有目录和公共目录的区别及使用场景是什么?</think>### 解决 Android 执行 `chmod 777 /storage/emulated` 失败 (Permission denied) 的方法 您在尝试修改 `/storage/emulated` 目录权限时遇到的 `Permission denied` 错误,是由于 Android 的安全机制限制。以下是分步解决方案: --- ### 一、根本原因分析 1. **Linux 权限限制** `/storage/emulated` 的所有者通常是 `root` 或 `system` 用户,普通用户无权修改(引用[3])。 2. **SELinux 强制保护** Android 的 SELinux 策略会阻止未授权的权限修改(引用[1][2])。 3. **Scoped Storage 限制** Android 10+ 引入了存储隔离机制,禁止直接修改共享存储路径(引用[1])。 --- ### 二、解决方案(按操作风险排序) #### ✅ 方案 1:使用应用私有目录(推荐,无需 root) ```java // 在代码中获取应用私有目录 File privateDir = getExternalFilesDir(null); String savePath = privateDir + "/abc.apk"; ``` - **优势**:无需任何权限声明,100% 兼容所有 Android 版本 - **路径示例**:`/storage/emulated/0/Android/data/包名/files/abc.apk` #### ✅ 方案 2:适配公共目录访问(Android 10+) 1. 在 `AndroidManifest.xml` 添加: ```xml <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <!-- Android 10+ 需要额外声明 --> <application android:requestLegacyExternalStorage="true"> ``` 2. 请求运行时权限: ```java if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { if (!Environment.isExternalStorageManager()) { Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION); startActivity(intent); } } ``` #### ⚠️ 方案 3:ADB 临时修改(需 root) ```bash adb shell su # 临时禁用 SELinux setenforce 0 # 修改目标目录权限(非整个 /storage/emulated) chmod 777 /storage/emulated/0/Download/abc.apk # 恢复 SELinux setenforce 1 ``` #### 🚫 高风险方案(仅限开发测试) ```bash # 在 root 设备上强制修改(可能破坏系统) adb shell su mount -o remount,rw /system chcon u:object_r:unlabeled:s0 /storage/emulated/0 # 修改 SELinux 上下文 chmod 777 /storage/emulated/0/Download mount -o remount,ro /system ``` --- ### 三、针对三星设备的特殊处理 1. 在 `AndroidManifest.xml` 添加三星专用权限: ```xml <!-- 解决三星机型兼容问题 --> <uses-permission android:name="com.sec.android.provider.badge.permission.READ"/> <uses-permission android:name="com.sec.android.provider.badge.permission.WRITE"/> ``` 2. 检查存储重定向: ```java if (Build.MANUFACTURER.equalsIgnoreCase("samsung")) { // 使用 MediaStore API 访问文件 ContentValues values = new ContentValues(); values.put(MediaStore.Downloads.DISPLAY_NAME, "abc.apk"); Uri uri = getContentResolver().insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values); } ``` --- ### 四、最佳实践建议 1. **路径选择优先级**: ```mermaid graph LR A[存储位置] --> B{是否需要共享} B -->|是| C[使用 MediaStore API] B -->|否| D[应用私有目录] ``` 2. **权限检查模板**: ```java public boolean checkStoragePermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { return Environment.isExternalStorageManager(); } else { return ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PERMISSION_GRANTED; } } ``` 3. **错误处理**: ```java try { // 文件操作代码 } catch (SecurityException e) { // 处理权限错误 Log.e("TAG", "权限不足: " + e.getMessage()); } catch (FileNotFoundException e) { // 处理三星机型特有错误 if (e.getMessage().contains("EACCES")) { requestStoragePermission(); } } ``` --- ### 五、各 Android 版本适配策略 | 版本 | 策略 | |-------------|----------------------------------------------------------------------| | Android 9- | 使用 `WRITE_EXTERNAL_STORAGE` + 运行时权限 | | Android 10 | 添加 `android:requestLegacyExternalStorage="true"` | | Android 11+ | 使用 `MANAGE_EXTERNAL_STORAGE` 或迁移到 MediaStore/SAF API | > **重要提示**:Google Play 对 Android 11+ 应用使用 `MANAGE_EXTERNAL_STORAGE` 有严格审核,需证明必要性[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值