首页 > 代码库 > NYOJ 330

NYOJ 330

这道题一开始的想法是模拟除法,记录商和余数,然后判断余数即可(当余数为0/余数开始重复出现时,结束)

代码如下:

技术分享
 1  
 2 #include <stdio.h>
 3 #include <cmath>
 4 #include <string.h>
 5 #include <cstring>
 6 #include <iostream> 
 7 #include <cmath>  
 8 #include <cstdlib>
 9 using namespace std;
10 //测试1063
11 bool test(int data[],int num,int bar,int yu[],int yushu){
12     int time = 0;
13     for(int i=0;i<num;i++){
14         if(data[i]==bar&&bar!=0&&yu[i]==yushu) time++;
15         if(time==2) return 0;
16     }
17     return 1;
18 }
19 
20 int main(){
21     int t;
22     cin>>t;
23     while(t--){
24         int n;
25         cin>>n; 
26         if(n<0){
27             cout<<"-";
28             n = -1*n;
29         }
30         
31         if(n==1){
32             cout<<"1\n";
33             continue;
34         }
35         else{
36             int data[100010],yu[100010];  
37             int num=0,shang = 10,chushu = 10,sign = 0,yushu = 10;
38             while(test(data,num,shang,yu,yushu)){
39                 shang = chushu/n;
40                 data[num] = shang;
41                 yushu = chushu%n;
42                 yu[num] =yushu;
43                 num++;
44                 
45                 chushu = yushu *10;
46                 if(yushu==0){
47                     sign = 1;
48                     break;
49                 }     
50             }
51             
52             if(sign==1) num+=1;
53             cout<<"0.";
54             for(int i=0;i<num-1;i++){
55                 cout<<data[i];
56             } 
57             cout<<endl;
58             
59         }
60         
61     }                
62     return 0;
63 }
64         
View Code

这里写法最大的问题是在记录余数时,采取了顺序记录的策略。这样就要求,在比较时需要遍历一遍余数数组,假如输出商有n位,那么时间复杂度为O(n2).  结果超时了。

考虑到可用空间换时间,可优化“余数查重”的代价。(类比于计数排序中的用空间换时间的策略,设立一个余数的vis[]数组,由于余数<n,而n<=100000,故只需要开一个大小为100010的数组,如果vis[yushu]=1,就说明该余数已经取过(初始化余数数组都为0);),如此,时间复杂度变更为O(n).

代码如下:

 1 #include <stdio.h>
 2 #include <cmath>
 3 #include <string.h>
 4 #include <cstring>
 5 #include <iostream> 
 6 #include <cmath>  
 7 #include <cstdlib>
 8 using namespace std;
 9 //测试1063
10 
11 int main(){
12     int t;
13     cin>>t;
14     while(t--){
15         int n;
16         cin>>n; 
17         if(n<0){
18             cout<<"-";
19             n = -1*n;
20         }
21         
22         if(n==1){
23             cout<<"1\n";
24             continue;
25         }
26         else{
27             int data[100010],yu[100010]={0};  
28             int num=0,chushu = 1,yushu = 1; 
29             yu[yushu] = 1;
30             while(1){  
31                 chushu = yushu *10; 
32                 data[num++] = chushu/n;  //把商记录起来     
33                 yushu = chushu%n;         //计算余数 
34                 
35                 if(yushu==0||yu[yushu] ) break; //如果余数为0或者出现过,则说明整除或够一个循环节 
36                 yu[yushu] =1;               //比起上一个写法高效的地方,用空间换时间   
37             } 
38             
39             cout<<"0.";
40             for(int i=0;i<num;i++){
41                 cout<<data[i];
42             } 
43             cout<<endl;
44             
45         }
46         
47     }                
48     return 0;
49 }

 

NYOJ 330