如果两个整数各位数字的和是一样的,则被称为是“朋友数”,而那个公共的和就是它们的“朋友证号”。例如 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);}
}
一些碎碎念
其实,之所以会出现两种方法,是因为前面写链表法的时候,就想到还有更加简单的,但是既然做都做了,总不可能只做一半就放弃吧,结果硬是把它写出来。