本文主要是介绍蛮力法——狱吏问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目大意:狱吏问题)某王国对囚犯进行大赦,让一狱吏n次通过一排锁着的n间牢房,每通过一次按所定规则转动门锁,每转动一次,原来锁着的被打开,原来打开的被锁上;通过n次后,门锁开着的,牢房中的犯人放出,否则犯人不得获释.转动门锁的规则是这样的,第一次通过牢房,要转动每一把门锁,即把全部锁打开;第二次通过牢房时,从第二间开始转动,每隔一间转动一次;第k次通过牢房,从第k间开始转动,每隔k-1 间转动一次;问通过n次后,那些牢房的锁仍然是打开的?
三种方法:
所有方法中锁的状态:1代表锁着,0代表开着
1、纯暴力法
C++代码:
#include<iostream>
using namespace std;
int main(){int n,*prisoner;cin>>n;prisoner=new int[n+1];for(int i=0;i<=n;i++)prisoner[i]=1;for(int i=1;i<=n;i++) //i--->表示狱吏是第几轮走过for(int j=i;j<=n;j=j+i) //j--->需要改变的锁的编号 prisoner[j]=1-prisoner[j];for(int i=1;i<=n;i++)if(prisoner[i]==0)cout<<i<<" ";return 0;
}
2、利用因子数
C++代码:
//利用因子数的个数得出每个编号的锁中间变换状态的次数//eg i=4时,它的因子有1,2,4,所以他在第1,2,4轮时会变换状态
#include<iostream>
using namespace std;
int main(){int n,*prisoner;cin>>n;prisoner=new int[n+1];for(int i=0;i<=n;i++)prisoner[i]=1;for(int i=1;i<=n;i++){int count=1;for(int j=2;j<=i;j++)if(i%j==0)count++;if(count%2==0)prisoner[i]=1;elseprisoner[i]=0;}for(int i=1;i<=n;i++)if(prisoner[i]==0)cout<<i<<" ";return 0;
}
3、找规律
C++代码:
//利用规律来判断//规律:当锁的标号为一个数的平方时,那么最后它会开着
eg.(其中1代表锁着,0代表开着)
锁的标号:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
最后状态:0 1 1 0 1 1 1 1 0 1 1 1 1 1 1 0
#include<iostream>
#include<math.h>
using namespace std;
int main(){int n,*prisoner;cin>>n;prisoner=new int[n+1];for(int i=0;i<=n;i++)prisoner[i]=1;for(int i=1;i<=sqrt(n);i++){int temp=i*i;if(temp<=n)prisoner[temp]=0;}for(int i=1;i<=n;i++)if(prisoner[i]==0)cout<<i<<" ";return 0;
}
这篇关于蛮力法——狱吏问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!