开灯问题 —— POJ 1218 THE DRUNK JAILER

2024-09-05 04:08
文章标签 poj 1218 drunk jailer 开灯 问题

本文主要是介绍开灯问题 —— POJ 1218 THE DRUNK JAILER,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

对应POJ 题目:点击打开链接

THE DRUNK JAILER
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 24831 Accepted: 15569

Description

A certain prison contains a long hall of n cells, each right next to each other. Each cell has a prisoner in it, and each cell is locked. 
One night, the jailer gets bored and decides to play a game. For round 1 of the game, he takes a drink of whiskey,and then runs down the hall unlocking each cell. For round 2, he takes a drink of whiskey, and then runs down the 
hall locking every other cell (cells 2, 4, 6, ?). For round 3, he takes a drink of whiskey, and then runs down the hall. He visits every third cell (cells 3, 6, 9, ?). If the cell is locked, he unlocks it; if it is unlocked, he locks it. He 
repeats this for n rounds, takes a final drink, and passes out. 
Some number of prisoners, possibly zero, realizes that their cells are unlocked and the jailer is incapacitated. They immediately escape. 
Given the number of cells, determine how many prisoners escape jail.

Input

The first line of input contains a single positive integer. This is the number of lines that follow. Each of the following lines contains a single integer between 5 and 100, inclusive, which is the number of cells n. 

Output

For each line, you must print out the number of prisoners that escape when the prison has n cells. 

Sample Input

2
5
100

Sample Output

2
10

题意:

可以理解成这样:有n盏灯,一开始所有灯都是灭的,第1轮对序号是1的倍数的灯操作(原来亮的就熄灭,原来灭的就点亮);第2轮对序号是2的倍数的灯操作、、、第i轮对序号是i的倍数的灯操作,直到第n轮过后,问剩下多少盏灯是亮的。


思路1:枚举,不解释


思路2:

这个问题有如下性质:

1、如果某盏灯被操作的次数是奇数,那它就是亮的(一开始是灭的)。

2、对于第i盏灯(i从1开始),如果i是完全平方数,那这盏灯被操作的次数就是奇数。


性质1是显然的:第0次是灭的,第1次是亮的,第2次是灭的。。。

性质2的证明:

对于序号为18这盏灯,它被操作的轮数是:第1轮,第2轮,第3轮,第6轮,第9轮,第18轮。被操作了6次,是偶数次。它被操作的轮数其实就是它的所有约数。一个大于1的非完全平方数的约数个数都是成对出现的,即都是偶数。而完全平方数,如16,其约数为1,2,4,8,16。是5个,因为4的平方是16,所以4只算一次。所以完全平方数的约数是奇数。


对于题目要求,序号为i的灯的被操作次数就是i的所有约数的个数a,如果a是奇数,那序号为i的灯最后就是亮的。归结起来就是如果i是完全平方数,那序号为i的灯最后就是亮的。所以题目最后求的就是1~n的完全平方数的个数。答案不难得出,就是将n开方向下取整(可以这样理解:x^2 <= n,解出x = 根号n向下取整,那x就是满足要求的最大值,如果k属于1~x,那k^2都是完全平方数,共有x个)。


思路1代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define M 550
int a[M];int main()
{//freopen("in.txt","r",stdin);int n, x, i, j, ans;scanf("%d", &n);while(n--){ans = 0;memset(a, 0, sizeof(a));scanf("%d", &x);for(i = 1; i <= x; i++){for(j = i; j <= x; j += i){if(a[j]) a[j] = 0;else a[j] = 1;}}for(i = 1; i <= x; i++)if(a[i]) ans++;printf("%d\n", ans);}return 0;
}

思路2代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>int main()
{//freopen("in.txt","r",stdin);int n, x;scanf("%d", &n);while(n--){scanf("%d", &x);printf("%d\n", (int)sqrt(double(x)));}return 0;
}

两种写法的空间都是140k左右,时间都是0ms,不太理解~






这篇关于开灯问题 —— POJ 1218 THE DRUNK JAILER的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1137904

相关文章

好题——hdu2522(小数问题:求1/n的第一个循环节)

好喜欢这题,第一次做小数问题,一开始真心没思路,然后参考了网上的一些资料。 知识点***********************************无限不循环小数即无理数,不能写作两整数之比*****************************(一开始没想到,小学没学好) 此题1/n肯定是一个有限循环小数,了解这些后就能做此题了。 按照除法的机制,用一个函数表示出来就可以了,代码如下

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

购买磨轮平衡机时应该注意什么问题和技巧

在购买磨轮平衡机时,您应该注意以下几个关键点: 平衡精度 平衡精度是衡量平衡机性能的核心指标,直接影响到不平衡量的检测与校准的准确性,从而决定磨轮的振动和噪声水平。高精度的平衡机能显著减少振动和噪声,提高磨削加工的精度。 转速范围 宽广的转速范围意味着平衡机能够处理更多种类的磨轮,适应不同的工作条件和规格要求。 振动监测能力 振动监测能力是评估平衡机性能的重要因素。通过传感器实时监

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s

poj 1511 Invitation Cards(spfa最短路)

题意是给你点与点之间的距离,求来回到点1的最短路中的边权和。 因为边很大,不能用原来的dijkstra什么的,所以用spfa来做。并且注意要用long long int 来存储。 稍微改了一下学长的模板。 stack stl 实现代码: #include<stdio.h>#include<stack>using namespace std;const int M

poj 3259 uva 558 Wormholes(bellman最短路负权回路判断)

poj 3259: 题意:John的农场里n块地,m条路连接两块地,w个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。 任务是求你会不会在从某块地出发后又回来,看到了离开之前的自己。 判断树中是否存在负权回路就ok了。 bellman代码: #include<stdio.h>const int MaxN = 501;//农场数const int

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

poj 1287 Networking(prim or kruscal最小生成树)

题意给你点与点间距离,求最小生成树。 注意点是,两点之间可能有不同的路,输入的时候选择最小的,和之前有道最短路WA的题目类似。 prim代码: #include<stdio.h>const int MaxN = 51;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int P;int prim(){bool vis[MaxN];

poj 2349 Arctic Network uva 10369(prim or kruscal最小生成树)

题目很麻烦,因为不熟悉最小生成树的算法调试了好久。 感觉网上的题目解释都没说得很清楚,不适合新手。自己写一个。 题意:给你点的坐标,然后两点间可以有两种方式来通信:第一种是卫星通信,第二种是无线电通信。 卫星通信:任何两个有卫星频道的点间都可以直接建立连接,与点间的距离无关; 无线电通信:两个点之间的距离不能超过D,无线电收发器的功率越大,D越大,越昂贵。 计算无线电收发器D