8枚硬币:
void Compare(int a[], int i, int j , int k){//i :较重的 j :较轻的 k:正确的
if(a[i] > a[k]){
printf("第%d 个硬币是假币,偏重\n" , i + 1);
}if(a[j] < a[k]){
printf("第%d 个硬币是假币,偏轻\n" , j + 1);
}
}
void Coin1(int a[])
{
int i;
int add1 = 0, add2 = 0; //每组的重量
for(i = 0; i < 3 ; i++){
add1 += a[i];
}
for(i = 3; i < 6 ; i++){
add2 += a[i];
}
if(add1 == add2){ //假币在第三组
if(a[6] > a[7]){
Compare(a, 6, 7, 0);
}else{
Compare(a, 7, 6, 0);
}
}
if(add1 > add2){ //真币在第三组
if(a[0] + a[3] > a[1] + a[4]){
Compare(a, 0, 4, 1);
}else if(a[0] + a[3] == a[1] + a[4]){
Compare(a, 2, 5, 0);
}else{
Compare(a, 1, 3, 0);
}
}else{
if(a[0] + a[3] > a[1] + a[4]){
Compare(a, 3, 1, 0);
}else if(a[0] + a[3] == a[1] + a[4]){
Compare(a, 5, 2, 0);
}else{
Compare(a, 4, 0, 1);
}
}
}
n枚硬币:
//得到真币下标
int getRel(int coin[], int m, int n){
if(n - m + 1 <= 2){
printf("无解");
return -1;
}else{
if(coin[1] == coin[0])
return 0;
else
return 2;
}
}
void getCoin(int n, int coin[]){
int i = 0, s0, s1, s2;
srand((int)time(NULL));
while(1){
s0 = rand() % 10; //真币的重量
if(s0 != 0)
break;
}
while(1){
coin[i] = s0;
i++;
if(i == n)
break;
}
s1 = rand() % n; //生成假币的下标
while(1){
s2 = rand() % 10; //假币的重量
if(s2 != 0 && s2 != s0)
break;
}
i = 0;
while(1){
if(i == s1){
coin[i] = s2;
break;
}
i++;
}
}
//硬币总重量 下标从 m到n
int Sum_Coin(int coin[], int m , int n){
int res = 0;
int i;
if(m > n)
return 0;
for(i = m; i <= n; i++){
res += coin[i];
}
return res;
}
//将硬币分为4组 1组有(N-(N%3))/3 2组有(N-(N%3))/3 3组有(N-(N%3))/3 4组有 N%3
int Coin2(int coin[], int m, int n, int relCoin){
int vary = n - m + 1; //硬币数量的数量
if(vary == 1){
return m;
}
if(vary == 2){ //只剩下两个点时 如果 第一个点 和rel相等 就返回第二个点
if(Sum_Coin(coin, m, m) == Sum_Coin(coin, relCoin, relCoin))
return n;
else
return m;
}
int restCoin = vary % 3; // 分组4的硬币数量
// int vary2 = (vary - restCoin) / 3; //第1,2,3组里的硬币数量
int vary2 = vary/3;
//第一组和第二组比较
if(Sum_Coin(coin, m, m + vary2 - 1) == Sum_Coin(coin, m+vary2, m+vary2*2 - 1)){
//第一组和第三组比较
if(Sum_Coin(coin, m, m + vary2 - 1) == Sum_Coin(coin, m+vary2*2, m+vary2*3 - 1))
Coin2(coin, n - restCoin+1, n, relCoin);//相等的话,假币在第四组里
else
Coin2(coin, m+vary2*2, m+vary-1, relCoin);//不相等的话,假币在第三组里
}else{//第一堆不等于第二堆 在第一堆或第二堆里
if(Sum_Coin(coin, m, m+vary2-1) == Sum_Coin(coin, m+vary2*2, m+vary2*3-1))
//第一堆合第三堆相等 假硬币在第二堆里
Coin2(coin, m + vary2, m + vary2 * 2 - 1, relCoin);
else//不相等 假币在第一堆里;
Coin2(coin, m, m + vary2 - 1, relCoin);
}
}
打印:
void printCoin(int coin[], int n){
int i = 0;
for(i = 0; i < n; i++){
printf("coin[ %d ] = %d\t", i + 1, coin[i]);
}
printf("\n");
}
完整代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void Compare(int a[], int i, int j , int k){//i :较重的 j :较轻的 k:正确的
if(a[i] > a[k]){
printf("第%d 个硬币是假币,偏重\n" , i + 1);
}if(a[j] < a[k]){
printf("第%d 个硬币是假币,偏轻\n" , j + 1);
}
}
void Coin1(int a[])
{
int i;
int add1 = 0, add2 = 0; //每组的重量
for(i = 0; i < 3 ; i++){
add1 += a[i];
}
for(i = 3; i < 6 ; i++){
add2 += a[i];
}
if(add1 == add2){ //假币在第三组
if(a[6] > a[7]){
Compare(a, 6, 7, 0);
}else{
Compare(a, 7, 6, 0);
}
}
if(add1 > add2){ //真币在第三组
if(a[0] + a[3] > a[1] + a[4]){
Compare(a, 0, 4, 1);
}else if(a[0] + a[3] == a[1] + a[4]){
Compare(a, 2, 5, 0);
}else{
Compare(a, 1, 3, 0);
}
}else{
if(a[0] + a[3] > a[1] + a[4]){
Compare(a, 3, 1, 0);
}else if(a[0] + a[3] == a[1] + a[4]){
Compare(a, 5, 2, 0);
}else{
Compare(a, 4, 0, 1);
}
}
}
//比较n枚硬币
//得到真币下标
int getRel(int coin[], int m, int n){
if(n - m + 1 <= 2){
printf("无解");
return -1;
}else{
if(coin[1] == coin[0])
return 0;
else
return 2;
}
}
void getCoin(int n, int coin[]){
int i = 0, s0, s1, s2;
srand((int)time(NULL));
while(1){
s0 = rand() % 10; //真币的重量
if(s0 != 0)
break;
}
while(1){
coin[i] = s0;
i++;
if(i == n)
break;
}
s1 = rand() % n; //生成假币的下标
while(1){
s2 = rand() % 10; //假币的重量
if(s2 != 0 && s2 != s0)
break;
}
i = 0;
while(1){
if(i == s1){
coin[i] = s2;
break;
}
i++;
}
}
//硬币总重量 下标从 m到n
int Sum_Coin(int coin[], int m , int n){
int res = 0;
int i;
if(m > n)
return 0;
for(i = m; i <= n; i++){
res += coin[i];
}
return res;
}
//将硬币分为4组 1组有(N-(N%3))/3 2组有(N-(N%3))/3 3组有(N-(N%3))/3 4组有 N%3
int Coin2(int coin[], int m, int n, int relCoin){
int vary = n - m + 1; //硬币数量的数量
if(vary == 1){
return m;
}
if(vary == 2){ //只剩下两个点时 如果 第一个点 和rel相等 就返回第二个点
if(Sum_Coin(coin, m, m) == Sum_Coin(coin, relCoin, relCoin))
return n;
else
return m;
}
int restCoin = vary % 3; // 分组4的硬币数量
// int vary2 = (vary - restCoin) / 3; //第1,2,3组里的硬币数量
int vary2 = vary/3;
//第一组和第二组比较
if(Sum_Coin(coin, m, m + vary2 - 1) == Sum_Coin(coin, m+vary2, m+vary2*2 - 1)){
//第一组和第三组比较
if(Sum_Coin(coin, m, m + vary2 - 1) == Sum_Coin(coin, m+vary2*2, m+vary2*3 - 1))
Coin2(coin, n - restCoin+1, n, relCoin);//相等的话,假币在第四组里
else
Coin2(coin, m+vary2*2, m+vary-1, relCoin);//不相等的话,假币在第三组里
}else{//第一堆不等于第二堆 在第一堆或第二堆里
if(Sum_Coin(coin, m, m+vary2-1) == Sum_Coin(coin, m+vary2*2, m+vary2*3-1))
//第一堆合第三堆相等 假硬币在第二堆里
Coin2(coin, m + vary2, m + vary2 * 2 - 1, relCoin);
else//不相等 假币在第一堆里;
Coin2(coin, m, m + vary2 - 1, relCoin);
}
}
void printCoin(int coin[], int n){
int i = 0;
for(i = 0; i < n; i++){
printf("coin[ %d ] = %d\t", i + 1, coin[i]);
}
printf("\n");
}
int main()
{
printf("-----------------------八枚硬币-------------------\n");
int a[8];
getCoin(8, a);
printCoin(a, 8);
Coin1(a);
printf("----------------------n枚硬币----------------------\n");
int n;
printf("\n几枚硬币??");
scanf("%d", &n);
int coin[n];
// int i, m;
getCoin(n, coin);
/* printf("输入硬币重量:\n");
for(i = 0; i < n; i++){
scanf("%d", &m);
coin[i] = m;
}*/
printCoin(coin, n);
int relcoin = getRel(coin, 0, n);
printf("rel = %d", relcoin);
int fakeCoin = Coin2(coin, 0, n - 1, relcoin);
printf("第%d枚硬币是假币", fakeCoin + 1);
if(fakeCoin != 0){
if(coin[fakeCoin] > coin[0])
printf(" 假币偏重");
else
printf(" 假币偏轻");
}else{
if(coin[fakeCoin] > coin[1])
printf(" 假币偏重");
else
printf(" 假币偏轻");
}
return 0;
}
运行结果: