Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) |
问题如上
在这个题目上耗费了一下午加一晚上的时间。。= =真是略显水。
考虑了很多。。最终正确的代码如下:
#include <iostream>
#include <cstring>
#define max 32768
using namespace std;
int p;
bool num[32768];
short cal[32768];
short prime[32768];
bool current[32768];
int cm(int a, int b);//求公约数并返回最小公约数,b不是素数
void GetPrime();
int main()
{
int cn, i, no, cur, j;
GetPrime();
cin >> cn;
while(cn --)
{
memset(current,1, sizeof(current));
cin >> cur;
if(num[cur])
cal[cur] = cur - 1;
else
{
no = 1;
for(i = 0; i < p && prime[i] < cur; i++)
{
if(cur % prime[i] == 0)
for(j = prime[i]; j <= cur; j += prime[i])
{
current[j] = false;
}
}
for(i = 2; i <= cur; i++)
{
if(current[i])
no++;
}
cal[cur] = no;
}
cout << cal[cur] << endl;
}
return 0;
}
void GetPrime()
{
int i, j, temp;
memset(num, 1, sizeof(num));
p = 2;
prime[0] = 2;
prime[1] = 3;
for(i = 1; i <= 3; i++)
num[i] = true;
for(i = 4; i <= 32768; i++)
{
if(num[i])
{
for(j = 0; j < p; j++)
{
if(i % prime[j] == 0)
{
num[i] = false;
temp = i;
while(temp <= 32768)
{
num[temp] = false;
temp += i;
}
break;
}
}
if(num[i])
prime[p++] = i;
}
}
}
一开始考虑到了各种问题。发现了如下问题:
1.数组下标不正确,与上方不相对应
2.对于sizeof理解不深刻,以及储存空间不够深刻,造成开始的memory溢出;
3.筛法原来就是开一个bool型的数组,然后从里面去除。计算素数的时候使用了筛法。(但是我一直不知道- -);
4.打表的方法可以用于数据量大并且可能有重复的情况。
5.建立全局变量以后里面的值如果并未初始化,存的全部是0.起码int,short,bool型是这个样子。
算法分析:
先求出在该范围的素数,然后求出输入数字的素数因子,使用筛法计算非素数数量。
本题设计到了最小公约数,素数。该题是一道水题,完全可以不计算所有的素数来求出。。但是我还是球了- -。
附加筛法代码,转载自:点击打开链接
//筛选法处理
#include <stdio.h>
#include <string.h>
char hash[32770]; //使用字符型的减少了内存的开销
int main()
{
int i,j,t,n,count;
while(scanf("%d",&t)!=EOF)
{
while(t--)
{
scanf("%d",&n);
memset(hash,0,sizeof(hash)); //每次都要赋初始值
count = 0;
for(i=2;i<=n;i++)
{
if(n%i==0)
for(j=i;j<=n;j+=i) // 这里是用了筛选法,注意的是j=i为初始条件 ,而不是j=i+i;
hash[j] = 1;
}
for(i=1;i<=n;i++)
if(hash[i]==0)
count++;
printf("%d\n",count);
}
}
return 0;
}
#include <stdio.h>
int ans;
void Eu(int n){
for(int i = 2; i * i <= n;++i){
if(!(n%i)){
ans *= i - 1;
n /= i;
while(!(n%i)){
ans *= i;n/=i;
}
}
}
if(n > 1){
ans *= n -1;
}
return ;
}
int main(){
int n,test_case;
scanf("%d",&test_case);
while(test_case--){
scanf("%d",&n);
ans = 1;
Eu(n);
printf("%d\n",ans);
}
return 0;
}