89 分糖果
作者: xxx时间限制: 10S章节: 一维数组
问题描述 :
肖恩和帕特里克是兄弟,他们从他们的父母那里得到了很多糖果。每一块糖具有一个正整数的价值,孩子们希望分他们得到的糖果。首先,肖恩将这些糖果分成两堆,并选择一堆给帕特里克。然后,帕特里克将尝试计算每堆的价值,其中每堆的价值是那堆糖果价值的总和,如果他觉得没有平等的价值,他将开始哭了起来。
不幸的是,帕特里克太小了,所以不能正确的计算。他只会二进制无进位的加法。比如说,他想算12(二进制为1100)加5(二进制为101),他会把最右边的两位加法算正确,但是第三位会忘记进位。(即0+0=0,0+1=1,1+0=1,1+1=0)
因此,帕特里克算12加5的结果为9。下面几个是帕特里克算的结果:
5 + 4 = 1
7 + 9 = 14
50 + 10 = 56
肖恩数学很好,他想得到价值总和更高的糖果并且不让他的弟弟哭。如果可能,他会分成两个非空的糖果袋,让帕特里克认为,双方都有相同的值的糖果。给你每一袋糖果每一块糖果的价值,我们想知道是否可能让帕特里克相信他们得到糖果价值的总量是相同的。如果可能计算出肖恩能得到的最大的价值。
输入说明 :
第一行输入T(1<T<10),表示接下来输入T组测试数据。
每组测试数据占一行,每行包含以下数据,N C1 C2 … Cn(其中N(2 ≤ N ≤ 10)代表从父母那里得到糖果的总数,C(1 ≤ Ci ≤ 100)代表每块糖果的价值)
输出说明 :
若不能输出NO,若能则输出肖恩得到的最大的价值。
输入范例 :
2
5 1 2 4 5 8
3 3 5 6
输出范例 :
NO
11
代码
/*
T90 循环数
*/
#include<stdio.h>
#include<string.h>
#define MAX_SIZE 10
int isLoopingNum(int n);
int main() {
int M = 0, i = 0;
scanf("%d", &M);
i = M + 1;
while (1) {
if (isLoopingNum(i)) {
printf("%d\n", i);
break;
}
else
i++;
}
return 0;
}
// 判断循环数
int isLoopingNum(int n) {
int i = 0, j = 0;
int num = 0;// 前一个被选中的数
int temp = 0;
int count = 0;// 已选的数字个数
int digitAmt = 0;// 一个数包含的数字个数
int flag[10] = {0};// flag[i]=1表示数字i在某个数的已经出现
int stack[MAX_SIZE] = {0};// 保存一个数的各个位
while (n) {
if (flag[n % 10] == 1 || n % 10 == 0)// 有重复数字或者有零,不是循环数
return 0;
stack[i++] = n % 10;
flag[n % 10] = 1;// 标记某个数字已经出现
n /= 10;
}
digitAmt = i;
for (j = 0; j < i / 2; j++) {// 翻转各位数字
temp = stack[j];
stack[j] = stack[i - j - 1];
stack[i - j - 1] = temp;
}
i = 0;
count++;
num = stack[i];
memset(flag, 0, sizeof(flag));// 重置标记
flag[num] = 1;
while (count < digitAmt) {// 循环取数
i = (i + num) % digitAmt;
count++;
if (flag[stack[i]] == 1)// 数字已经出现,不是循环数
return 0;
else {
num = stack[i];
flag[num] = 1;// 标记数字
}
}
if ((i + num) % digitAmt != 0)// 没有回到起点,不是循环数
return 0;
return 1;
}
害,感觉我判断循环数那里写的好复杂……