UVA, 967 Circular
题意:给你一个区间,问其中是否存在素数变化位数后仍为素数 例:19937, 99371, 93719, 37199, 71993 问区间中有几个
思路:打印素数表,循环判断即可……
ps:( ̄ε(# ̄)(终于对了,…….超时是因为每次输入一个数重复查找前面满足circle的数
AC代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cmath> 6 using namespace std; 7 8 #define MAXN 1000001 9 10 int cnt,counts; 11 long l,r; 12 bool isprime[MAXN]; 13 long prime[MAXN],f[MAXN]; 14 15 bool datecin() 16 { 17 counts=0; 18 scanf("%ld",&l); 19 if(l==-1) 20 return false; 21 scanf("%ld",&r); 22 return true; 23 } 24 25 bool circle(long num) 26 { 27 char ss[20]; 28 sprintf(ss,"%ld",num); 29 string s=ss; 30 int len=s.length(); 31 for(int i=0;i<len;i++) 32 { 33 string tmp; 34 tmp+=s.substr(i); 35 tmp+=s.substr(0,i); 36 int n=atoi(tmp.c_str()); 37 if(!isprime[n]) 38 return false; 39 } 40 return true; 41 } 42 43 void getprime() 44 { 45 int i,j; 46 memset(isprime,1,sizeof(isprime)); 47 isprime[0]=isprime[1]=cnt=0; 48 for(i=2;i<MAXN;i++) 49 { 50 if(isprime[i]) 51 prime[cnt++]=i; 52 for(j=0;j<cnt&&i*prime[j]<MAXN;j++) 53 { 54 isprime[i*prime[j]]=false; 55 if(!(i%prime[j]))break; 56 } 57 } 58 f[0] = f[1] = 0; 59 for (int i = 2; i < MAXN; i++) 60 { 61 if (circle(i)) f[i] = f[i - 1] + 1; 62 else f[i] = f[i - 1]; 63 } 64 65 } 66 67 68 void showres() 69 { 70 counts=f[r]-f[l-1]; 71 if(counts==0) 72 printf("No Circular Primes.\n"); 73 else if(counts==1) 74 printf("1 Circular Prime.\n"); 75 else if(counts>1) 76 printf("%d Circular Primes.\n",counts); 77 } 78 79 80 int main() 81 { 82 83 getprime(); 84 while(datecin()) 85 { 86 //datecal(); 87 showres(); 88 89 } 90 return 0; 91 }
关于circle()函数,参考了大神的代码:http://wuli2496.blog.163.com/blog/static/44754999201479115124756
int sprintf( char *buffer, const char *format, [ argument] … )
作用:将格式化的数据写入某个字符串:sprintf(字符串,格式化字符串,数据)
例:sprintf(s,"%d",num);
basic_string substr(size_type _Off = 0,size_type _Count = npos) const;
作用:从所需字符串的指定位置开始拷贝一定长度的字符串 所需字符串.substr(初始位置,长度)
例:str2=str1.substr(0,5);不包括初始位置字符
ps:substr 是string类拥有的函数,若没有规定长度,则从初始位置复制到字符串末
int atoi(const char *nptr);
作用:把字符串类型转化为整型
例:n=atoi(s);
const char*c_str()
作用:返回当前字符串的首地址指针
后面再去学习一下其他复制的函数
关于前几次TLE,分析了一下应该是每次代码都重复地寻找前面满足Circle的数字,
这次我们在打印素数表的时候将其储存,因而避免了TLE.
ps:下面TLE的Circle函数不能满足前面几位的数字的circle因而计算错误,所以参考了大神的
果然字符串用起来比单纯数字清爽一些……
2016.4.22
TLE代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 using namespace std; 6 7 #define MAXN 1000001 8 #define ll 9 //#define onlineJudge 10 int cnt,counts; 11 long l,r; 12 bool isprime[MAXN]; 13 long prime[MAXN]; 14 15 bool datecin() 16 { 17 counts=0; 18 scanf("%ld",&l); 19 if(l==-1) 20 return false; 21 scanf("%ld",&r); 22 return true; 23 } 24 25 void getprime() 26 { 27 int i,j; 28 memset(isprime,1,sizeof(isprime)); 29 isprime[0]=isprime[1]=cnt=0; 30 for(i=2;i*i<MAXN;i++) 31 { 32 if(isprime[i]) 33 { 34 for(j=i*i;j<MAXN;j+=i) 35 { 36 if(isprime[j]) 37 { 38 isprime[j]=false; 39 } 40 } 41 42 } 43 } 44 for(i=2;i<MAXN;i++) 45 { 46 if(isprime[i]) 47 prime[cnt++]=i; 48 } 49 } 50 51 int getw(long num) 52 { 53 int i=0; 54 while(num!=0) 55 { 56 num/=10; 57 i++; 58 } 59 return i; 60 } 61 62 bool circle(long num) 63 { 64 int w=getw(num); 65 int g=1; 66 for(int i=1;i<w;i++)g*=10; 67 for(int i=1;i<w;i++) 68 { 69 num=num/10+(num%10)*g; 70 //cout<<num<<endl; 71 if(!isprime[num]) 72 return false; 73 } 74 return true;; 75 } 76 77 void datecal() 78 { 79 for(int i=0;i<cnt;i++) 80 { 81 if(prime[i]>r) 82 break; 83 if(prime[i]>=l&&prime[i]<=r) 84 { 85 if(circle(prime[i])) 86 counts++; 87 } 88 } 89 } 90 91 void showres() 92 { 93 if(counts==0) 94 printf("No Circular Primes.\n"); 95 else if(counts==1) 96 printf("1 Circular Prime.\n"); 97 else if(counts>1) 98 printf("%d Circular Primes.\n",counts); 99 } 100 101 102 int main() 103 { 104 105 getprime(); 106 #ifdef ll 107 while(datecin()) 108 { 109 datecal(); 110 #ifdef onlineJudge 111 freopen("d:\\uva_967.txt", "w", stdout); 112 #endif // onlineJudge 113 showres(); 114 115 } 116 #endif // ll 117 return 0; 118 }
=s= 嗯,目前状态TLE,先搁这了,我做做其他的( ̄ε(# ̄)☆╰╮( ̄▽ ̄///)(你的学习之魂呢
(╯‵□′)╯︵┻━┻为啥TLE啊,我都改成线性筛法了 2016.4.18