训练赛题解

突然想到好久以前做完这份题目没写题解。蛮来写写吧。很多细节已经忘记了。。

第一题

很简单的字符串比对是否b包含a。不包含就报NO,包含就YES。。坑爹的第一次!!。把strlen放在了for循环里面。。就超时了。。超时了。。

注意:for里面的条件每次也会重新计算。

A - All in All
Time Limit:1000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u

Description

You have devised a new encryption technique which encodes a message by inserting between its characters randomly generated strings in a clever way. Because of pending patent issues we will not discuss in detail how the strings are generated and inserted into the original message. To validate your method, however, it is necessary to write a program that checks if the message is really encoded in the final string.

Given two strings s and t, you have to decide whether s is a subsequence of t, i.e. if you can remove characters from t such that the concatenation of the remaining characters is s.

Input

The input contains several testcases. Each is specified by two strings s, t of alphanumeric ASCII characters separated by whitespace.The length of s and t will no more than 100000.

Output

For each test case output "Yes", if s is a subsequence of t,otherwise output "No".

Sample Input

sequence subsequence
person compression
VERDI vivaVittorioEmanueleReDiItalia
caseDoesMatter CaseDoesMatter

Sample Output

Yes
No
Yes
No

下附代码
 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<cmath>
 5 #define INF 1000000
 6 char s[100005],t[100005];
 7 int main()
 8 {
 9     int i=0,j=0,s_len,t_len;
10     while(scanf("%s%s",s,t)!=EOF)
11     {
12         i=0;j=0;
13         s_len=strlen(s);
14         t_len=strlen(t);
15         for(i;i<s_len&&j<t_len;)
16             if(s[i]==t[j])
17                 {i++;j++;}
18             else
19                 j++;
20         if(i==strlen(s))
21             printf("Yes\n");
22         else
23             printf("No\n");
24     }
25     return 0;
26 }

 

第二题

找规律。。其实也可以还原。但是找到规律的话也是可以做的。就是写代码的时候要认真点。思路是相邻做差,得到一个新的数组,新数组有数字,说明肯定有差括号,是1,然后这个新数组如果有一串0,说明原来的数字都是相等的,则第一位0肯定是1,但是接下来的0,就要继续往前找对应的括号,然后增加数字,具体的已经忘记了。但是就是找规律。这题1A。

B - Parencodings
Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u

Description

Let S = s1 s2...s2n be a well-formed string of parentheses. S can be encoded in two different ways:
q By an integer sequence P = p1 p2...pn where pi is the number of left parentheses before the ith right parenthesis in S (P-sequence).
q By an integer sequence W = w1 w2...wn where for each right parenthesis, say a in S, we associate an integer which is the number of right parentheses counting from the matched left parenthesis of a up to a. (W-sequence).

Following is an example of the above encodings:

S (((()()())))
P-sequence 4 5 6666
W-sequence 1 1 1456

Write a program to convert P-sequence of a well-formed string to the W-sequence of the same string.

Input

The first line of the input contains a single integer t (1 <= t <= 10), the number of test cases, followed by the input data for each test case. The first line of each test case is an integer n (1 <= n <= 20), and the second line is the P-sequence of a well-formed string. It contains n positive integers, separated with blanks, representing the P-sequence.

Output

The output file consists of exactly t lines corresponding to test cases. For each test case, the output line should contain n integers describing the W-sequence of the string corresponding to its given P-sequence.

Sample Input

2
6
4 5 6 6 6 6
9 
4 6 6 6 6 8 9 9 9

Sample Output

1 1 1 4 5 6
1 1 2 4 5 1 1 3 9

下附代码:
 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<queue>
 7 #define INF 1000005
 8 using namespace std;
 9 queue<int>q;
10 int s[1000005]={0},mark[1000005];
11 int main()
12 {
13     int n,first,late,i,m,ans,t;
14     scanf("%d",&n);
15     while(n--)
16     {
17         for(i=0;i<30;i++)
18             {s[i]=0;mark[i]=0;}
19         scanf("%d",&m);
20         first=0;
21         for(i=0;i<m;i++)
22             {
23                 scanf("%d",&late);
24                 s[i]=late-first;
25                 first=late;
26             }
27         for(i=0;i<m;i++)
28         {
29             if(s[i])
30             {
31               if(i!=m-1)
32                     printf("1 ");
33                 else
34                     printf("1\n");
35             }
36             else
37             {
38                 t=i;ans=0;
39                 while(!s[t]||mark[t]==s[t])
40                 {
41                     ans+=mark[t];
42                     t--;
43                 }
44                 while(mark[t]+1==s[t])
45                 {
46                     mark[t]++;
47                     ans+=s[t];
48                     t--;
49                     while(!s[t]||mark[t]==s[t])
50                     {
51                         ans+=mark[t];
52                         t--;
53                     }
54                 }
55                 mark[t]++;
56                 if(i!=m-1)
57                     printf("%d ",ans+mark[t]+1);
58                 else
59                     printf("%d\n",ans+mark[t]+1);
60             }
61         }
62     }
63     return 0;
64 }

 

第三题

一个二叉树的前序中序序列,还原后序序列,用到了递归分治的思想,主要要分清楚两个序列的头和尾在哪里,然后可以通过找根找到中序序列中间的根,从而继续分开这两个序列。关键代码是下面这个

if(k-cc)
        turn(aa+1,k-cc+aa,cc,k-1);
if(dd-k)
        turn(aa+k-cc+1,bb,k+1,dd);

错了两次,算是一道考细节的递归。
下附代码:
 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<queue>
 7 #define INF 1000000
 8 using namespace std;
 9 char a[50],b[50],c[50];
10 void turn(int aa,int bb,int cc,int dd)//n是前序m是中序
11 {
12     int k=0;
13     while(a[aa]!=b[k])
14     {
15         k++;
16     }//找根
17     if(k-cc)
18         turn(aa+1,k-cc+aa,cc,k-1);
19     if(dd-k)
20         turn(aa+k-cc+1,bb,k+1,dd);
21     printf("%c",a[aa]);
22 }
23 int main()
24 {
25     int i,m,n,ans,t,bg,j,num,k,h=0,sum=0;
26     while(scanf("%s%s",a,b)!=EOF)
27     {
28         t=strlen(a);
29         turn(0,t-1,0,t-1);
30         for(i=1;i<=t;i++)
31             printf("%c",c[i]);
32         printf("\n");
33     }
34     return 0;
35 }

 

第四题:

BFS就行。用队列来存,注意一下具体细节。

D - Catch That Cow
Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Description

Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.

* Walking: FJ can move from any point X to the points X - 1 or X + 1 in a single minute
* Teleporting: FJ can move from any point X to the point 2 × X in a single minute.

If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?

Input

Line 1: Two space-separated integers: N and K

Output

Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.

Sample Input

5 17

Sample Output

4

Hint

The fastest way for Farmer John to reach the fugitive cow is to move along the following path: 5-10-9-18-17, which takes 4 minutes.

下附代码:

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<queue>
 7 #define INF 1000000
 8 using namespace std;
 9 queue<int>q;
10 int vis[1000005]={0};
11 int main()
12 {
13     int a,b,cot,ans,t,mark=0,noww;
14     scanf("%d%d",&a,&b);
15     if(a==b)
16         printf("0\n");
17     else
18     {
19         if(a+1==b||a-1==b||a*2==b)
20             printf("1\n");
21         else
22         {
23             q.push(a);
24             vis[a]=1;
25             while(!q.empty())
26             {
27                 ans=q.front();
28                 q.pop();
29                 if(ans-1>=0)
30                     {
31                         noww=ans-1;
32                         if(!vis[noww])
33                         {vis[noww]=vis[ans]+1;q.push(noww);}
34                         if(noww==b)
35                             {printf("%d\n",vis[noww]-1);break;}
36                     }
37                 if(ans+1<INF)
38                 {
39                     noww=ans+1;
40                     if(!vis[noww])
41                         {vis[noww]=vis[ans]+1;q.push(noww);}
42                     if(noww==b)
43                             {printf("%d\n",vis[noww]-1);break;}
44                 }
45                 if(ans*2<INF)
46                 {
47                     noww=ans*2;
48                     if(!vis[noww])
49                         {vis[noww]=vis[ans]+1;q.push(noww);}
50                     if(noww==b)
51                         {printf("%d\n",vis[noww]-1);break;}
52                 }
53             }
54         }
55     }
56     return 0;
57 }

 

第五题:

一道判断是不是连通的,用并查集就可以判断,但是要做一点小处理,存储的时候如果就一个数字就不管他,如果有两个或两个以上就用第一个数字当父亲,让后面其他的数字与其关联。

E - The Suspects
Time Limit:1000MS     Memory Limit:20000KB     64bit IO Format:%I64d & %I64u

Description

Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, was recognized as a global threat in mid-March 2003. To minimize transmission to others, the best strategy is to separate the suspects from others.
In the Not-Spreading-Your-Sickness University (NSYSU), there are many student groups. Students in the same group intercommunicate with each other frequently, and a student may join several groups. To prevent the possible transmissions of SARS, the NSYSU collects the member lists of all student groups, and makes the following rule in their standard operation procedure (SOP).
Once a member in a group is a suspect, all members in the group are suspects.
However, they find that it is not easy to identify all the suspects when a student is recognized as a suspect. Your job is to write a program which finds all the suspects.

Input

The input file contains several cases. Each test case begins with two integers n and m in a line, where n is the number of students, and m is the number of groups. You may assume that 0 < n <= 30000 and 0 <= m <= 500. Every student is numbered by a unique integer between 0 and n−1, and initially student 0 is recognized as a suspect in all the cases. This line is followed by m member lists of the groups, one line per group. Each line begins with an integer k by itself representing the number of members in the group. Following the number of members, there are k integers representing the students in this group. All the integers in a line are separated by at least one space.
A case with n = 0 and m = 0 indicates the end of the input, and need not be processed.

Output

For each case, output the number of suspects in one line.

Sample Input

100 4
2 1 2
5 10 13 11 12 14
2 0 1
2 99 2
200 2
1 5
5 1 2 3 4 5
1 0
0 0

Sample Output

4
1
1
下附代码:
 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<queue>
 7 #define INF 1000005
 8 using namespace std;
 9 int f[30005],mark[30005],mark1[30005]={0};
10 int finding(int x)
11 {
12     if(x!=f[x])
13         f[x]=finding(f[x]);
14     return f[x];
15 }
16 int together(int x,int y)
17 {
18     int f1=finding(x);
19     int f2=finding(y);
20     if(f1!=f2)
21         {f[f2]=f1;return 1;}
22     return 0;
23 }
24 int main()
25 {
26     int i,m,n,ans,t,bg,j,num,k,h=0,cot=0,sum,late,temp;
27     while(scanf("%d%d",&n,&m)&&(n!=0||m!=0))
28     {
29         for(i=0;i<=n;i++)
30             f[i]=i;
31         k=0;
32         while(m--)
33         {
34             scanf("%d",&num);
35             if(num>1)
36                 {
37                     scanf("%d",&bg);
38                     if(!mark1[bg])
39                     {mark[k++]=bg;mark1[bg]=1;}
40                     for(i=1;i<num;i++)
41                         {
42                             scanf("%d",&late);
43                             together(bg,late);
44                             if(!mark1[late])
45                             {mark[k++]=late;mark1[late]=1;}
46                         }
47                 }
48             else if(num==1)
49                 {scanf("%d",&temp);
50                 if(!mark1[temp])
51                 {mark[k++]=temp;mark1[temp]=1;}}
52         }
53         sum=0;
54         for(i=0;i<k;i++)
55         {
56             if(finding(0)==finding(mark[i]))
57                 sum++;
58         }
59         if(sum==0)
60             printf("1\n");
61         else
62             printf("%d\n",sum);
63         for(i=0;i<k;i++)
64             mark1[mark[i]]=0;
65     }
66     return 0;
67 }

 

第六题:

一道超级水的最小生成树,用kruskal就可以。但是注意储存,只需要上三角就行。之前不小心数组开小了。就超了。。

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<queue>
 7 #define INF 1000000
 8 using namespace std;
 9 int f[100005];
10 struct node
11 {
12     int x;
13     int y;
14     int k;
15 }c[100005];
16 int cmp(struct node a,struct node b)
17 {
18     return a.k<b.k;
19 }
20 int finding(int x)
21 {
22     if(f[x]!=x)
23         f[x]=finding(f[x]);
24     return f[x];
25 }
26 int together(int x,int y)
27 {
28     int f1,f2;
29     f1=finding(x);
30     f2=finding(y);
31     if(f1!=f2)
32         {f[f2]=f1;return 1;}
33     return 0;
34 }
35 int main()
36 {
37     int i,m,n,ans,t,a,b,bg,j,num,k,h=0,sum=0;
38     while(scanf("%d",&n)!=EOF)
39     {
40         h=0;ans=0;sum=0;
41         for(i=0;i<100005;i++)
42             f[i]=i;
43         for(i=1;i<=n;i++)
44             for(j=1;j<=n;j++)
45                 {
46                     scanf("%d",&c[h].k);
47                     if(c[h].k!=0)
48                     {
49                         c[h].x=i;c[h].y=j;
50                         h++;
51                     }
52                 }
53         sort(c,c+h,cmp);
54         for(i=1;i<h;i++)
55         {
56             ans=together(c[i].x,c[i].y);
57             if(ans==1)
58             {
59                 sum+=c[i].k;
60             }
61         }
62         printf("%d\n",sum);
63     }
64     return 0;
65 }

 

第七题:

这题是最短路径,用dijkstra会超的原因居然是模板错了!!。最后只能用floyd反而过了。。无语。。模板害死人啊。

            if(s[j]==false&&dis[j]<mining)
            {
                u=j;mining=mapp[v][j];
            }
这句才是真的
G - Tram
Time Limit:1000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u

Description

Tram network in Zagreb consists of a number of intersections and rails connecting some of them. In every intersection there is a switch pointing to the one of the rails going out of the intersection. When the tram enters the intersection it can leave only in the direction the switch is pointing. If the driver wants to go some other way, he/she has to manually change the switch.

When a driver has do drive from intersection A to the intersection B he/she tries to choose the route that will minimize the number of times he/she will have to change the switches manually.

Write a program that will calculate the minimal number of switch changes necessary to travel from intersection A to intersection B.

Input

The first line of the input contains integers N, A and B, separated by a single blank character, 2 <= N <= 100, 1 <= A, B <= N, N is the number of intersections in the network, and intersections are numbered from 1 to N.

Each of the following N lines contain a sequence of integers separated by a single blank character. First number in the i-th line, Ki (0 <= Ki <= N-1), represents the number of rails going out of the i-th intersection. Next Ki numbers represents the intersections directly connected to the i-th intersection.Switch in the i-th intersection is initially pointing in the direction of the first intersection listed.

Output

The first and only line of the output should contain the target minimal number. If there is no route from A to B the line should contain the integer "-1".

Sample Input

3 2 1
2 2 3
2 3 1
2 1 2

Sample Output

0
下附代码:
 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<queue>
 7 #define INF 1000000
 8 using namespace std;
 9 int mapp[105][105],dis[105];
10 bool s[105];
11 int n;
12 void dijkstra(int v)
13 {
14     int i,j;
15     for(i=1;i<=n;i++)
16     {
17         dis[i]=mapp[v][i];
18         s[i]=false;
19     }
20     s[v]=true;
21     dis[v]=0;
22     for(i=2;i<=n;i++)
23     {
24         int mining=INF,u=v;
25         for(j=1;j<=n;j++)
26         {
27             if(s[j]==false&&dis[j]<mining)
28             {
29                 u=j;mining=mapp[v][j];
30             }
31         }
32         s[u]=true;
33         for(j=1;j<=n;j++)
34         {
35             if(s[j]==false&&mapp[u][j]<INF)
36                 if(mapp[u][j]+dis[u]<dis[j])
37                     dis[j]=mapp[u][j]+dis[u];
38         }
39     }
40 }
41 int main()
42 {
43     int i,m,ans,t,a,b,bg,j,num,k;
44     while(scanf("%d%d%d",&n,&a,&b)!=EOF)
45     {for(i=0;i<105;i++)
46         for(j=0;j<105;j++)
47             mapp[i][j]=INF;
48     for(i=1;i<=n;i++)
49     {
50         scanf("%d",&num);
51         for(j=0;j<num;j++)
52             {
53                 scanf("%d",&bg);
54                 if(j==0)
55                     mapp[i][bg]=0;
56                 else
57                     mapp[i][bg]=1;
58             }
59     }
60     /*for(i=1;i<=n;i++)
61         {for(j=1;j<=n;j++)
62             printf("%d ",mapp[i][j]);
63         cout<<endl;}*/
64     dijkstra(a);
65     /*for(j=1;j<=n;j++)
66         for(i=1;i<=n;i++)
67             for(k=1;k<=n;k++)
68                 if(mapp[i][j]+mapp[j][k]<mapp[i][k])
69                     mapp[i][k]=mapp[i][j]+mapp[j][k];*/
70     /*for(i=1;i<=n;i++)
71         printf("%d ",dis[i]);
72     cout<<endl;*/
73     if(dis[b]==INF)
74         printf("-1\n");
75     else
76         printf("%d\n",dis[b]);
77     /*if(mapp[a][b]==INF)
78         printf("-1\n");
79     else
80         printf("%d\n",mapp[a][b]);*/
81     }
82     return 0;
83 }

 

第八题:

这题以前做过,就是简单的素数筛一下,从小到大选择就好,注意。没有偶数。。我还调了半天。

J - Goldbach's Conjecture
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Description

In 1742, Christian Goldbach, a German amateur mathematician, sent a letter to Leonhard Euler in which he made the following conjecture:
Every even number greater than 4 can be
written as the sum of two odd prime numbers.

For example:
8 = 3 + 5. Both 3 and 5 are odd prime numbers.
20 = 3 + 17 = 7 + 13.
42 = 5 + 37 = 11 + 31 = 13 + 29 = 19 + 23.

Today it is still unproven whether the conjecture is right. (Oh wait, I have the proof of course, but it is too long to write it on the margin of this page.)
Anyway, your task is now to verify Goldbach's conjecture for all even numbers less than a million.

Input

The input will contain one or more test cases.
Each test case consists of one even integer n with 6 <= n < 1000000.
Input will be terminated by a value of 0 for n.

Output

For each test case, print one line of the form n = a + b, where a and b are odd primes. Numbers and operators should be separated by exactly one blank like in the sample output below. If there is more than one pair of odd primes adding up to n, choose the pair where the difference b - a is maximized. If there is no such pair, print a line saying "Goldbach's conjecture is wrong."

Sample Input

8
20
42
0

Sample Output

8 = 3 + 5
20 = 3 + 17
42 = 5 + 37
下附代码:
 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<queue>
 7 #define INF 1000005
 8 using namespace std;
 9 queue<int>q;
10 int s[1000005]={0},primee[1000005];
11 void prime()
12 {
13     int i,k=1,cot;
14     for(i=2;i<INF;i++)
15     {
16         if(s[i]==0)
17             primee[k++]=i;
18         cot=2;
19         while(cot*i<INF)
20         {
21             s[i*cot]=1;
22             cot++;
23         }
24     }
25 }
26 int main()
27 {
28 
29     int i=1,n;
30     prime();
31     //for(i=1;i<100;i++)
32         //cout<<primee[i]<<" ";
33     while(scanf("%d",&n)&&n!=0)
34     {
35         i=1;
36         while(s[n-primee[i]])
37         {
38             i++;
39         }
40         printf("%d = %d + %d\n",n,primee[i],n-primee[i]);
41     }
42     return 0;
43 }

 

第九题:

简单的进位。字符串转成数字进行加减就好。

K - Primary Arithmetic
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Description

Children are taught to add multi-digit numbers from right-to-left one digit at a time. Many find the "carry" operation - in which a 1 is carried from one digit position to be added to the next - to be a significant challenge. Your job is to count the number of carry operations for each of a set of addition problems so that educators may assess their difficulty.

Input

Each line of input contains two unsigned integers less than 10 digits. The last line of input contains 0 0.

Output

For each line of input except the last you should compute and print the number of carry operations that would result from adding the two numbers, in the format shown below.

Sample Input

123 456
555 555
123 594
0 0

Sample Output

No carry operation.
3 carry operations.
1 carry operation.

下附代码:
 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<cmath>
 5 char a[200005],b[200005];
 6 int main()
 7 {
 8     int carry,ans,t,s;
 9     while(scanf("%s%s",a,b)&&(a[0]!='0'||b[0]!='0'))
10     {
11         carry=0;
12         t=strlen(a)-1;s=strlen(b)-1;ans=0;
13         while(t>=0&&s>=0)
14         {
15             if((a[t]-48)+(b[s]-48)+carry>9)
16                 {
17                     carry=(a[t]-48)+(b[s]-48)+carry;
18                     ans++;
19                     carry/=10;
20                 }
21             t--;s--;
22         }
23         if(t<0)
24         {
25             while(s>=0)
26             {
27                  if((b[s]-48)+carry>9)
28                 {
29                     carry=(b[s]-48)+carry;
30                     ans++;carry/=10;s--;
31                 }
32                 else
33                     break;
34             }
35         }
36         if(s<0)
37         {
38             while(t>=0)
39             {
40                 if((a[t]-48)+carry>9)
41                 {
42                     carry=(a[t]-48)+carry;
43                     ans++;carry/=10;t--;
44                 }
45                 else
46                     break;
47             }
48         }
49         if(ans==0)
50             printf("No carry operation.\n");
51         else if(ans==1)
52             printf("1 carry operation.\n");
53         else
54             printf("%d carry operations.\n",ans);
55     }
56     return 0;
57 }

 

第十题:
就是在n的范围内,互质的分数的个数。其实就是欧拉函数在1-n范围内求和,打个线性欧拉函数筛就搞定了。
L - Farey Sequence
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Description

The Farey Sequence Fn for any integer n with n >= 2 is the set of irreducible rational numbers a/b with 0 < a < b <= n and gcd(a,b) = 1 arranged in increasing order. The first few are
F2 = {1/2}
F3 = {1/3, 1/2, 2/3}
F4 = {1/4, 1/3, 1/2, 2/3, 3/4}
F5 = {1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5}

You task is to calculate the number of terms in the Farey sequence Fn.

Input

There are several test cases. Each test case has only one line, which contains a positive integer n (2 <= n <= 10 6). There are no blank lines between cases. A line with a single 0 terminates the input.

Output

For each test case, you should output one line, which contains N(n) ---- the number of terms in the Farey sequence Fn.

Sample Input

2
3
4
5
0

Sample Output

1
3
5
9
下附代码:
 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<queue>
 7 #define INF 1000005
 8 using namespace std;
 9 int target[INF],phi[INF];
10 bool pri[INF];
11 int main()
12 {
13     int i,m,n,ans,t,bg,j,num,k,h=0,cot=0;
14     long long int sum=0;
15     for(i=2;i<INF;i++)
16     {
17         if(pri[i]==false)
18         {
19             target[cot++]=i;
20             phi[i]=i-1;
21         }
22         for(j=0;j<cot&&i*target[j]<INF;j++)
23         {
24             pri[i*target[j]]=true;
25             if(i%target[j]==0)
26                 phi[i*target[j]]=phi[i]*target[j];
27             else
28                 phi[i*target[j]]=phi[i]*(target[j]-1);
29         }
30     }
31     while(scanf("%d",&n)&&n!=0)
32     {
33         sum=0;
34         for(i=2;i<=n;i++)
35             sum+=phi[i];
36         printf("%lld\n",sum);
37     }
38     return 0;
39 }

其实还有两题。但都是比较困难的题目了。。待以后有余力的话继续补充。

又结束了一次训练,感觉还是没什么长进,希望暑假能提高代码能力。。加油!


 

 

posted @ 2015-06-07 22:48  kingofprank  阅读(407)  评论(0编辑  收藏  举报