题目链接:
http://poj.org/problem?id=1218
http://acm.hdu.edu.cn/showproblem.php?pid=1337
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1350
题意:
一个喝醉了酒的监狱守卫干了这么一件事:
有n个房间
从1到n,每次把序号的倍数的那些门转换状态(关的开上,开的关上)求最后有几张门开着。
第一种方法直接模拟:
代码:
代码:#include <iostream> #include<cstdio> using namespace std; int main() { int n; scanf("%d",&n); while(n--) { int c[105]={1}; int y; int count=0; scanf("%d",&y); for(int i=2;i<=y;i++) for(int j=1;j*i<=y;j++) { if(c[i*j]==1) c[i*j]=0; else c[i*j]=1; } for(int i=1;i<=y;i++) if(c[i]==0) count++; printf("%d\n",count); } return 0; }
第二种方法:<span style="font-size: 12px;">但是经过观察发现,一个cell被开关的次数其实是有规律的,也就是这个cell的编号n的约数的数量;比如4,他的约数有1,2,4,所以编号为4的cell会在游戏的第1,2,4轮被开/关。又如果一个cell被开/关的最终次数为偶数次,则该cell最终也就是关闭的,这个cell里可怜的<span style="font-family: 'Times New Roman', Times, serif;">prisoner将无法上演《越狱》,只有cell编号的约数数量为奇数的,才有机会逃跑。所以,问题转换为,求一个数1~n中,有多少数有奇数个约数。</span></span><span style="font-size: 12px;"><span style="font-family: 'Times New Roman', Times, serif;"> </span></span>
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int t,n;
int cell[105]={0,1,1,1,2,2};
for(int i=6;i<=104;i++)
{
int sum=0;
for(int j=2;j<=i/2;j++)
if(!(i%j))
sum++;
cell[i]=cell[i-1]+sum%2;
}
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
printf("%d\n",cell[n]);
}
return 0;
}
第三种方法:
只有完全平方数才有奇数个因子,所以只需要求出n以内的完全平方数个数即可;
完全平方数个数=sqrt(n);
o(1)的解法,不用开数组,不用打表!
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
printf("%d\n",(int)sqrt(n*1.0));
}
return 0;
}