Fork me on GitHub

SCAU 2011 校赛 10307 Trees and Numbers

10307 Trees and Numbers

 

1.题意:
一个Case表示森林,森林有一棵至多棵树不等,每一棵树代表着一个素数,而森林代表着所有数经过某种结合产生的一个值 N。如果我给这森林加一个根成为一棵树,那么这个根节点表示的就是第N个素数,具体点来说:
2 是第一个素数,我们用一个节点表示它,在这个节点之上我再加一个节点,由于前面这个节点表示的N为2,所以新加的这个节点表示第 2 个素数即 3,在表示 3 的这个节点之上我再加一个新的节点那么就表示第 3 个素数即 5,在 5 之上再加一个新的节点,那么这时表示的是第 5 个素数即 11,不再增加节点的话,那么这棵树就表示一个值 11。
如果森林有两棵以上的数,那么这个森林表示的值 M 为各棵树表示的值相乘得到的结果。这时如果往森林里增加新节点表示为根将所有的树连接成一棵树,那么这个新节点表示的值为第 M 个素数,整棵新树表示的值同样也为第 M 个素数

 

2.解题思路:
首先,筛素数。根据题目给出的范围,筛出50000以为的素数,存储在数组Prime中,最好根据题目的要求将下标定为第几个素数,比如说 Prime[1] = 2, Prime[2] = 3;
然后,建树。根据题目输入的形式,可以用一个数组Parent存储 i 的双亲节点的“数组下标地址”为Parent[i], 考虑到孩子数目的不确定数,声明结构体,用孩子链表存储孩子节点,并且每个节点都要声明一个变量存储其表示的素数(具体声明可以看《数据结构》(严慧敏版)136页);
最后,遍历计算。首先要找到树根,如果数不止一棵的话,那么这片森林所代表的值为所有的树的值相乘得到的值,至于计算每棵树表示的值,采用深度优先遍历即可

 

Description

Can you find the rule of these equations?
Let me explain for you. There are only 3 definitions:
Every Tree represent a prime integer (prime integer is an integer that can only divide by 1 and itself. e.g. 2,3,5,7 etc.).
A forest (one or more trees) represents a integer which is the product of trees.
If we add a root for a forest (Let n to be the integer it represent) to build a tree, then this new tree represent the n-th prime integer.
For example , 2 is the first prime integer , we use one node to represent it , and 3 is the second , so we add a root to 2 , it become 3. 
Then add a root to 3 , we get the third prime ——5. If we add a root to 5? We get the fifth prime, which is 11. Also, while combine 3 and 5 ,
 we will get 15 since 15=3*5 . That is why 11 and 15 represent that in the figure.
Figure 2: 15=3*5 and 23 is the 9-th prime integer.
Now, give you a tree, can you find the integer it represents?

输入格式

The Input will contain multiple cases.
The first line contains an integer T, the number of test cases.
Then T cases follow.
The first line of each case, is a integer n(n>0) , that represents the number of nodes in the forest.
After that, there will be one line contains n integers. The i-th integer ai means that the father node of 
the i-th node is ai (0<=ai<=n) . And if ai=0, it just means that i-th node is a root of tree (0 is not a node).
You can assume that all this can exactly build a forest, and cases like:
2
2 1
is invalid and will not appear.

输出格式

For each case, output the answer in one line.
You may assume that all the answers are less than 50000.

输入样例

7
1
0
4
0 1 2 3
5
0 1 0 3 4
5
0 1 1 1 2
6
0 0 0 3 4 4
7
0 0 5 2 2 4 1
6
0 1 1 1 1 1

输出样例

2
11
15
37
68
69
131

提示

The 2-7th sample is in the figure 1.

作者

admin

 

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<malloc.h>
  4 #define MAXN 50000
  5 #define MAX_N 5200
  6 
  7 typedef struct child{
  8 //孩子节点 
  9     int ads; //此节点的下标 
 10     struct child *nextchild; //指向其兄弟 
 11 }child;
 12 
 13 typedef struct Tree{
 14     int num, value; //num 表示其孩子的个数,value 表示这棵树表示的素数值 
 15     struct child *firstchild; //指向其第一个孩子节点 
 16 }Tree;
 17 
 18 typedef struct forest{
 19     int num; //只是表示这片森林一共有几个节点,这个结构体可以省略 
 20     Tree note[MAX_N];
 21 }forest;
 22 
 23 forest equation;
 24 int prime[MAXN/2], parent[MAXN+2];
 25 
 26 int store_prime()
 27 {//筛出 50000 以内的素数存储到prime数组中,返回素数的个数 
 28     int i, j, cnt = 1;
 29     memset(prime, 0, sizeof(prime));
 30     memset(parent, 0, sizeof(parent));
 31     parent[0] = parent[1] = 1;
 32     for(i=2; i<MAXN+2; ++i)
 33     {
 34         if(!parent[i])
 35         {
 36             prime[cnt++] = i;
 37             for(j=i; j<MAXN+2; j += i)
 38             parent[j] = 1;
 39         }
 40     }
 41     return cnt;
 42 }
 43 
 44 void init_equation()
 45 {//初始化所有的节点 
 46     int i;
 47     for(i=1; i<=equation.num; ++i)
 48     {
 49         equation.note[i].num = 0;
 50         equation.note[i].value = 2;
 51         equation.note[i].firstchild = NULL;
 52     }
 53     return;
 54 }
 55 
 56 void insert(int cur, int elem)
 57 {//将节点 elem 插入到其双亲节点 cur 的孩子链表中 
 58     int i, n;
 59     child *str = NULL, *stp = NULL;
 60     n = equation.note[cur].num;
 61     stp = str = equation.note[cur].firstchild;
 62     for(i=1; i<n; ++i)
 63         stp = stp->nextchild;
 64     str = (child *)malloc(sizeof(child));
 65     str->nextchild = NULL, str->ads = elem;
 66     if(n == 0) equation.note[cur].firstchild = str;
 67     else stp->nextchild = str;
 68     ++equation.note[cur].num;
 69     return;
 70 }
 71 /* 
 72 void Print(int n)
 73 {//中间打印的测试函数,忽略 ~~ 
 74     int i, j, temp;
 75     child *str = NULL;
 76     for(i=1; i<=n; ++i)
 77     {
 78         printf("%d [%d] ", parent[i], i);
 79         temp = equation.note[i].num;
 80         str = equation.note[i].firstchild;
 81         if(temp != 0 )
 82         do
 83         {
 84             printf("%d ", str->ads);
 85             str = str->nextchild;    
 86         }while(--temp);
 87         printf("\n");
 88     }
 89 }
 90 */
 91 
 92 int Traverse(int cur)
 93 {//典型的深度查找,计算一棵树所代表的的素数值 
 94     int i, j, n, temp, k;
 95     child *str = equation.note[cur].firstchild;
 96     n = equation.note[cur].num;
 97     if(str == NULL) return equation.note[cur].value;
 98     for(i=1, k=1; i<=n; ++i)
 99     {
100         k *= Traverse(str->ads);
101         str = str->nextchild;    
102     }
103     return equation.note[cur].value = prime[k];
104 }
105 
106 int main()
107 {
108 //    freopen("input.txt", "r", stdin);
109     int i, j, t, T, n, point, k, flag, sum, num;
110     num = store_prime();
111     scanf("%d", &T);
112     while(T--)
113     {
114         scanf("%d", &n);
115         equation.num = n;
116         sum = 1;
117         init_equation();
118         for(i=1; i<=n; ++i)
119         {//parent数组存储指向 i 节点的 双亲的地址下标  
120             scanf("%d", &parent[i]);
121             if((point = parent[i]) != 0)
122                 insert(point, i);
123         }
124         for(i=1; i<=n; ++i)
125         {
126             if(parent[i] == 0)
127             {
128                 Traverse(i);
129                 sum *= equation.note[i].value;
130             }
131         }
132         printf("%d\n", sum);
133     }
134     return 0;
135 }

 

posted @ 2013-04-17 20:48  Gifur  阅读(326)  评论(0编辑  收藏  举报
TOP