PAT A1067 不懂!

//ac,勉强理解,还未完全自己实现 
//swap(pos[0],pos[pos[0]]);不太懂 
/*使用int型变量left记录除零以外的不在本位的数的个数
while(left>0){
    if(0在0号位上){
        找一个不在本位的数,令其与0交换
        交换次数++ 
    }
    while(0不在0号位上){
        将0所在位置的数与0交换
        交换次数++
        left--; 
    }    
} */
//我只能说一句,换个马甲,我真的看不懂!但是这是暂时的,我将各个击破 
//注意回到本位的不要再动
//注意设全局,当前不在本位的最小数,来控制复杂度在线性以内 
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=100010; 
int pos[maxn];//存放各数字当前所处的位置编号 
int main(){
    int n,ans=0;//ans表示交换的总次数 
    scanf("%d",&n);
    int left=n-1,num;//left存放除0以外的不在本位上的数的个数
    for(int i=0;i<n;i++){
        scanf("%d",&num);
        pos[num]=i;//num所处的位置为i。我靠好绕 
        if(num==i&&num!=0){
            left--;//令left减1 
        } 
    }
    int k=1;//k存放除0以外当前不在本位上的最小的数
    while(left>0){//只要还有数不在本位上。每次循环都要检查0是否在本位上,将作出不同的操作 
        if(pos[0]==0){//如果0在本位上,则寻找一最小的不在本位上的数交换
            while(k<n){//还有没回到本位的 
                if(pos[k]!=k){//找到一个当前不在本位上的数k 。如果在本位就跳过这里,k加1看是否在本位 
                    swap(pos[0],pos[k]);//将k与0位置交换 
                    ans++;//交换次数加1 
                    break; //退出本次循环,也就相当于执行完if(pos[0]==0)的条件句 
                }
                k++;//判断k+1是否在本位 
            }//直到找到一个不在本位并且最小的数 
        } 
        //只要0不在本位,就将0所在位置的数的当前所处位置与0的位置交换。这句话是对的,理解了你就懂了 
        while(pos[0]!=0){
            swap(pos[0],pos[pos[0]]);//将0余pos[0]交换
            ans++;//交换次数加1
            left--; //不在本位上的数的个数减1 
        } 
    }
    printf("%d\n",ans);//输出结果 
    return 0;
} 


看看我自己写的挫代码吧

//错了,这题,这题还蛮难的 
//这题我花了10分钟以内明白了大意是除了0以外有多少数字不在应该在的位置上。
//看书上说涉及到贪心。我想它因为只能和0换,怎么样换最少都应该是上一行描述的那样 
#include<cstdio>
#include<algorithm>
//#define LOCAL 
using namespace std;
const int maxn=100010;
int a[maxn]; 
int main(){
	#ifdef LOCAL
	freopen("A1067data.in","r",stdin);
	freopen("A1067data.out","w",stdout);
	#endif
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
	}
	//sort(a,a+n);
	int count=0;
	for(int i=0;i<n;i++){
		if(a[i]!=i)
			count++;
	}
	printf("%d\n",count);
	return 0;
} 


### 关于 PAT 乙级 1067 题的 C 语言解决方案 对于 PAT 乙级 1067 题目,即试密码问题,在处理时需注意输入输出的要求以及如何有效地比较字符串来判断用户输入是否匹配给定的正确密码。下面提供一种基于此需求设计的方法。 #### 输入与预处理 程序启动后会接收两部分初始数据:一是设定好的正确密码(长度不超过20字符),二是最大错误尝试次数N(不大于10次)。之后循环读取多行代表每次尝试输入的内容直到遇到特殊标记`#`为止[^2]。 ```c #include <stdio.h> #include <string.h> int main() { char correctPassword[21]; // 存储正确的密码 int maxAttempts; scanf("%s %d", correctPassword, &maxAttempts); getchar(); // 吃掉换行符 // ...后续逻辑... } ``` #### 尝试验证流程 每当接收到新的尝试时,应将其同之前保存下来的正确答案做对比;如果两者一致,则立即终止整个过程并告知成功登录;反之则减少剩余可失败的机会数量,并依据当前状态决定下一步动作——要么继续等待下一次猜测,要么因耗尽机会而提示锁定账户[^5]。 ```c while(maxAttempts--) { static char attempt[21]; fgets(attempt, sizeof(attempt), stdin); if(strcmp(attempt, "#\n") == 0) break; if(strcmp(correctPassword, strtok(attempt, "\r\n")) == 0){ puts("Welcome"); return 0; } } if(!maxAttempts) puts("Account locked"); else puts("Game over"); return 0; ``` 上述代码片段展示了核心功能实现方式,其中包含了基本控制结构的选择语句(`if`)和循环机制(`while`)的应用,同时也体现了标准库函数如`strcmp()`用于字符串操作的重要性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值