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