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); } } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了