如果兩個整數各位數字的和是一樣的,則被稱為是“朋友數”,而那個公共的和就是它們的“朋友證號”。例如 123 和 51 就是朋友數,因為 1+2+3 = 5+1 = 6,而 6 就是它們的朋友證號。給定一些整數,要求你統計一下它們中有多少個不同的朋友證號。
輸入格式
輸入第一行給出正整數 N。隨后一行給出 N 個正整數,數字間以空格分隔。題目保證所有數字小于10的四次方 。
輸出格式:
首先第一行輸出給定數字中不同的朋友證號的個數;隨后一行按遞增順序輸出這些朋友證號,數字間隔一個空格,且行末不得有多余空格。
輸入樣例
8
123 899 51 998 27 33 36 12
輸出樣例
4
3 6 9 26
Code
鏈表法
其實,那時候我怎么寫只要是因為看到N沒有限制,所以想到了用鏈表的辦法——因為鏈表也是不加限制的,除非借不到內存了。
#include <stdio.h>
#include <stdlib.h>
typedef struct Node{int num;int summary;struct Node *next;
} Node;
typedef Node* List ;
void addNode(List* list, int num, int *count) {int sum = 0;do sum += num % 10; while((num /= 10) > 0);if(*list) {List last = *list, last1;while(last != NULL) {if(last->num == sum) {last->summary++;goto out;}last1 = last;last = last->next;}Node *p = (Node*)malloc(sizeof(Node));p->num = sum;p->summary = 1;p->next = NULL;last1->next = p;} else {Node *p = (Node*)malloc(sizeof(Node));p->num = sum;p->summary = 1;p->next = NULL;*list = p;}(*count)++;out:;
}
void readList(List* list) {List last = *list;while(last != NULL) {if(last == *list) printf("%d", last->num);else printf(" %d", last->num);last = last->next;}
}
void sortList(List* list) {List last = *list, last1;int temp;while(last != NULL) {last1 = last->next;while(last1 != NULL) {if(last->num > last1->num) {// 交換位置temp = last->num;last->num = last1->num;last1->num = temp;temp = last->summary;last->summary = last1->summary;last1->summary = temp;}last1 = last1->next;}last = last->next;}
}
int main() {List head = NULL;int N, num, count = 0;scanf("%d", &N);for(int i = 0; i < N; i++) {scanf("%d", &num);addNode(&head, num, &count);}printf("%d\n", count);sortList(&head);readList(&head);
}
但是,這實在是太長了,還容易發生錯誤。
后來,我就想到了第二種方法,就是只用malloc
,這樣子錯誤率會降低一些。
連續空間法
#include <stdio.h>
#include <stdlib.h>
typedef struct Node{int num;int summary;
} Node;
int main() {int N, num, sum = 0, count = 0;scanf("%d", &N);Node *List = (Node*)malloc(sizeof(Node)*N), *p = List;for(int i = 0; i < N; i++) {sum = 0;scanf("%d", &num);while(num > 0) {sum += num % 10;num /= 10;}for(Node *q = List; q != p; q++) {if(sum == q->num) {q->summary++;goto out;}}p->num = sum;(p++)->summary = 1;count++;out:;}int temp;for(Node *q = List; q != p; q++) {for(Node *k = q+1; k != p; k++) {if(q->num > k->num) {temp = q->num;q->num = k->num;k->num = temp;temp = q->summary;q->summary = k->summary;k->summary = temp;}}}printf("%d\n", count);for(Node *q = List; q != p; q++) {if(q == List) printf("%d", *q);else printf(" %d", *q);}
}
一些碎碎念
其實,之所以會出現兩種方法,是因為前面寫鏈表法的時候,就想到還有更加簡單的,但是既然做都做了,總不可能只做一半就放棄吧,結果硬是把它寫出來。