C/java_时隔一年,再论田忌赛马(渊子赛马)

赛马是一古老的游戏,早在公元前四世纪的中国,处在诸侯割据的状态,历史上称为“战国时期”。在魏国作官的孙膑,因为受到同僚庞涓的迫害,被齐国使臣救出后,到达齐国国都。 赛马是当时最受齐国贵族欢迎的娱乐项目。上至国王,下到大臣,常常以赛马取乐,并以重金赌输赢。田忌多次与国王及其他大臣赌输赢,屡赌屡输。一天他赛马又输了,回家后闷闷不乐。孙膑安慰他说:“下次有机会带我到马场看看,也许我能帮你。” 孙膑仔细观察后发现,田忌的马和其他人的马相差并不远,只是策略运用不当,以致失败。 比赛前田忌按照孙膑的主意,用上等马鞍将下等马装饰起来,冒充上等马,与齐王的上等马比赛。第二场比赛,还是按照孙膑的安排,田忌用自己的上等马与国王的中等马比赛,在一片喝彩中,只见田忌的马竟然冲到齐王的马前面,赢了第二场。关键的第三场,田忌的中等马和国王的下等马比赛,田忌的马又一次冲到国王的马前面,结果二比一,田忌赢了国王。 就是这么简单,现在渊子也来赛一赛马。假设每匹马都有恒定的速度,所以速度大的马一定比速度小的马先到终点(没有意外!!)。不允许出现平局。最后谁赢的场数多于一半(不包括一半),谁就是赢家(可能没有赢家)。渊子有N(1≤N≤1000)匹马参加比赛。对手的马的数量与渊子马的数量一样,并且知道所有的马的速度。聪明的你来预测一下这场世纪之战的结果,看看渊子能否赢得比赛。

输入
输入有多组测试数据。 每组测试数据包括3行: 第一行输入N(1≤N≤1000)。表示马的数量。 第二行有N个整型数字,即渊子的N匹马的速度。 第三行有N个整型数字,即对手的N匹马的速度。 当N为0时退出。

输出
若通过聪明的你精心安排,如果渊子能赢得比赛,那么输出“YES”。 否则输出“NO”。

样例输入
5
2 3 3 4 5
1 2 3 4 5
4
2 2 1 2
2 2 3 1
0
样例输出
YES
NO

#include <stdio.h>

/* 数字版指针swap() */
void swap_int_pointer(int *a, int *b) {
	int temp;
	temp = *a;
	*a = *b;
	*b = temp;
}
void bubble_int_sort(int *p, int n);



int main() {
	//printf("test\n");
	int n;
	while (1) {
		/* 读取输入: */
		scanf("%d", &n);
		if (n == 0) {
			break;
		}
		int TianJiHorseSpeeds[1000], KingHorseSpeeds[1000];
		for (int i = 0; i < n; i++) {
			scanf("%d", &TianJiHorseSpeeds[i]);
		}
		for (int i = 0; i < n; i++) {

			scanf("%d", &KingHorseSpeeds[i]);
		}
		int winCounts = 0;
		//int draw = 0;
		/* 以下算法是通过小规模的输入示例总结出来的(将问题拆成更细的问题(有时却不是很有必要,如果若干个子问题比较好解决(或者是自己较为熟练掌握的),可以这么考虑拆问题) */
		/* 排序两人的马(从慢到快) */
		bubble_int_sort(TianJiHorseSpeeds, n);
		bubble_int_sort(KingHorseSpeeds, n);
		//先计算出田忌能够赢得的最多的场数(输或平局都无法为田忌争取更高的分值(这里认为是没有扣分的机制))
		for (int i = 0; i < n; i++) {
			//King
			int j = 0;

			for (j; j < n; j++) {
				//Yuanzi(TianJi)
				int delta = TianJiHorseSpeeds[j] - KingHorseSpeeds[i];
				if (delta > 0) {
					winCounts++;
					//将马的速度标记为1,标识该马不能够再次参赛.
					TianJiHorseSpeeds[j] = -1;
					KingHorseSpeeds[i] = -1;
					break;
				}
			}
		}

		//考虑平局的情况才行:
		//然而,我们亲手那个实例用该粗略的算法演示一下发现,平局的情况不能轻易确定,
		//由于所有比赛情况不外乎三种,那就退一步看输掉的情况:

		/* 考虑平局和输的情况: */
		int loseCounts = 0; //统计田忌输掉的场数(也就是齐王赢得场数.)
		int tempOfKingHorseIndex = 0;
		int i = 0;
		int j = 0;
		for (; i < n; i++) {
			//yuanzi(TianJi)
			int indexOfYuan = n - 1 - i;
			if (TianJiHorseSpeeds[indexOfYuan] == -1) {
				continue;
			}

			/* 由于数组内部有许多-1,无法只通过一个循环解决*/
			for (; j < n; j++) {
				//king
				/* 从后往前遍历田忌的马(由好到差);齐王的马则由差倒好,
				可以知道,此时齐王最差的马都不会慢于此时田忌最好的马,
				所以这时,田忌要么平局,要么输给齐王,所以田忌只能争取尽量多的平局.*/

				if (KingHorseSpeeds[j] == -1) {
					continue;
				}

				{
					if (TianJiHorseSpeeds[indexOfYuan] < KingHorseSpeeds[j]) {
						loseCounts++;
					} else {
						//平局:
					}
					//比赛后,将这一对马置为无效马。
					TianJiHorseSpeeds[indexOfYuan] = -1;
					KingHorseSpeeds[j] = -1;
					break;
				}

				/* 要直接统计平局的也可以 */
			}
		}
		/* 判断田忌赢得阐述和输的场数,来判断田忌最终否赢得比赛(而不是其他两种情况:NO) */
		if (winCounts > loseCounts) {
			printf("%s", "YES\n");
		} else {
			printf("%s", "NO\n");
		}
	}
	return 0;
}


void bubble_int_sort(int *p, int n) {
	void swap_int_pointer(int *a, int *b);
	/*冒泡法不需要设立最值flag. */
	for (int i = 0; i < n - 1; i++) {
		/*外重循环从LHS∈[0,n-2]选出一个元素;
		RHS = LHS+1 ∈ [1,n-1]
		单趟比较中:*/
		for (int j = 0; j <= n - 2 - i;
		        j++) {
			/*内重循环控制各趟排序的一系列比较中:控制LHS从[0,n-2-i]从0取遍n-2-i(i由外重循环弹出的表示现在是第i趟排序) */
			/*通过改变'<'为'>',可以从降序转为升序; 通过监视*(p+j)和*(p+j+1)可以知道当前(第j组)相邻量的值的情况 */
			if (*(p + j) > *(p + j + 1)) {
				/*或者写作if(p[j] < p[j+1])也可以*/
				swap_int_pointer(p + j, p + j + 1);
			}
		}
	}
}

import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);
        while (true) {
            //
            //int numberHorseN = scanner.nextInt();
            int numberHorseN = Integer.parseInt(scanner.nextLine());
            if (numberHorseN == 0) {
                break;
            }

            int[] YuanziHorseSpeeds = IntStringsToInts.intStringsToInts(scanner.nextLine());

            int[] KingHorseSpeeds = IntStringsToInts.intStringsToInts(scanner.nextLine());

            Arrays.sort(YuanziHorseSpeeds);
            Arrays.sort(KingHorseSpeeds);

            /*the algorithm */
            int winCounts = 0;

            for (int i = 0; i < numberHorseN; i++) {//king
                for (int i1 = 0; i1 < numberHorseN; i1++) {//yuanzi
                    if (YuanziHorseSpeeds[i1] > KingHorseSpeeds[i]) {
                        winCounts++;
                        YuanziHorseSpeeds[i1] = -1;//to ensure that the horse would never to win for YuanZi once more.
                        KingHorseSpeeds[i] = -1;
                        break;
                    }
                }
            }
            int loseCounts = 0;
            int j = 0;
            for (int i = 0; i < numberHorseN; i++) {//yuanzi
                int indexOfYuanzi = numberHorseN - 1 - i;
                if (YuanziHorseSpeeds[indexOfYuanzi] == -1) {
                    continue;
                }
                /*it's hard to solve the problem by means of only one for_loop
                 * we introduce a second for_loop*/
                for (; j < numberHorseN; j++) {//king
                    // boolean bool=KingHorseSpeeds[i]!=-1&&YuanziHorseSpeeds[indexOfYuanzi]!=-1;
                    if (KingHorseSpeeds[j] == -1) {
                        continue;
                    }
                    if(YuanziHorseSpeeds[indexOfYuanzi]<KingHorseSpeeds[j]){
                        loseCounts++;
                    }
                    YuanziHorseSpeeds[indexOfYuanzi]=-1;
                    KingHorseSpeeds[j]=-1;
                    break;
                }
            }//for
            if (winCounts>loseCounts) {
                System.out.println("YES");
            } else {
                System.out.println("NO");
            }
        }//while

    }

}
 class IntStringsToInts {
    public static int[] intStringsToInts(String intStrings) {
        /*universal read integer data method:*/
        String[] speedOfHorsesStrs = intStrings.split("\\s+");
        int lengthOfIntString = speedOfHorsesStrs.length;
        int[] ints = new int[lengthOfIntString];
        int indexOfInts = 0;
        for (String intStr : speedOfHorsesStrs) {
            ints[indexOfInts++] = Integer.parseInt(intStr);
        }
        return ints;
    }//intStringToINts()
}


探索过程版:

#include <stdio.h>

/* 数字版指针swap() */
void swap_int_pointer(int *a, int *b)
{
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}
void bubble_int_sort(int *p, int n);

int main()
{
   // printf("test\n");
    int n;
    while (1)
    {

        scanf("%d", &n);
        if (n == 0)
        {
            break;
        }
        int n1[1001], n2[1002];
        for (int i = 0; i < n; i++)
        {
            scanf("%d", &n1[i]);
        }
        for (int i = 0; i < n; i++)
        {
            /* code */
            scanf("%d", &n2[i]);
        }
        int count = 0;
        int draw = 0;

        bubble_int_sort(n1, n);
        bubble_int_sort(n2, n);

        for (int i = 0; i < n; i++)
        {
            //king
            /*  int hasEqual = 0;
			 int indexOfEqual1 = 0; */
            int j = 0;
            for (j; j < n; j++)
            {
                //Yuanzi
                int delta = n1[j] - n2[i];

                if (delta > 0)
                {
                    count++;
                    n1[j] = -1;
                    n2[i] = -1;
                    break;
                }
                /*            else if (delta == 0)
				           {
				               hasEqual++;
				               if (indexOfEqual1 == 0)
				                   indexOfEqual1 = j;
				           } */
            }
            //平局/输掉
            /*        if (j == n && hasEqual > 0)
			       {
			           printf("%d", draw);
			           draw++; //平局
			           n1[j] = -1;
			       } */
            //continue;
        }

        //考虑平局的情况才行:
        //然而,我们亲手那个实例用该粗略的算法演示一下发现,平局的情况不能轻易确定,
        //由于所有比赛情况不外乎三种,那就退一步看输掉的情况:

        /* 考虑平局和输的情况: */
        int lose = 0;
        for (int i = 0; i < n; i++)
        {
            //yuanzi
            /* code */
            for (int j = 0; j < n; j++)
            {
                //king
                /* code */
                /*      if((n1[n-1-i]!=-1)&&(n2[j]!=0))
				     {
				         if(n1[n-1-i]==n2[j]){
				             draw++;
				         }
				     } */
                int indexOfYuan = n - 1 - i;
                if (n1[indexOfYuan] != -1 && n2[j] != -1 && n1[indexOfYuan] < n2[j])
                {
                    lose++;
                    //
                    n1[indexOfYuan]=-1;
                    n2[j]=-1;
                    break;
                }
            }
        }

        //if (count > (n - draw) / 2)
        if (count > lose)
        {
            //printf("%d", count);
            printf("%s", "YES\n");

            /* code */
        }
        else
        {
            printf("%s", "NO\n");
        }
    }
}

void bubble_int_sort(int *p, int n)
{
    void swap_int_pointer(int *a, int *b);
    /*冒泡法不需要设立最值flag. */
    for (int i = 0; i < n - 1; i++)
    {
        /*外重循环从LHS∈[0,n-2]选出一个元素;
		RHS = LHS+1 ∈ [1,n-1]
		单趟比较中:*/
        for (int j = 0; j <= n - 2 - i;
             j++)
        {
            /*内重循环控制各趟排序的一系列比较中:控制LHS从[0,n-2-i]从0取遍n-2-i(i由外重循环弹出的表示现在是第i趟排序) */
            /*通过改变'<'为'>',可以从降序转为升序; 通过监视*(p+j)和*(p+j+1)可以知道当前(第j组)相邻量的值的情况 */
            if (*(p + j) > *(p + j + 1))
            {
                /*或者写作if(p[j] < p[j+1])也可以*/
                swap_int_pointer(p + j, p + j + 1);
            }
        }
    }
}

posted @ 2023-09-25 21:38  xuchaoxin1375  阅读(94)  评论(0)    收藏  举报  来源