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 @   xuchaoxin1375  阅读(75)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示