[NOIP2011普及组]瑞士轮 JAVA实现
2*N名编号为1~2N的选手共进行R轮比赛。每轮比赛开始前,以及所有比赛结束后,都会按照总分从高到低对选手进行一次排名。选手的总分为第一轮开始前的初始分数加上已参加过的所有比赛的得分和。总分相同的,约定编号较小的选手排名靠前。
每轮比赛的对阵安排与该轮比赛开始前的排名有关:第1名和第2名、第3名和第4名、……、第2K-1名和第2K名、……、第2N-1名和第2N名,各进行 一场比赛。每场比赛胜者得 1分,负者得0分。也就是说除了首轮以外,其它轮比赛的安排均不能事先确定,而是要取决于选手在之前比赛中的表现。
现给定每个选手的初始分数及其实力值,试计算在R轮比赛过后,排名第Q的选手编号是多少。我们假设选手的实力值两两不同,且每场比赛中实力值较高的总能获胜。
输入的第一行是三个正整数N、R、Q,每两个数之间用一个空格隔开,表示有2*N名选手、R轮比赛,以及我们关心的名次Q。
第二行是2*N个非负整数s1,s2,…,s2N,每两个数之间用一个空格隔开,其中si表示编号为i的选手的初始分数。
第三行是2*N个正整数w1,w2,…,w2N,每两个数之间用一个空格隔开,其中wi表示编号为i的选手的实力值。
输出只有一行,包含一个整数,即R轮比赛结束后,排名第Q的选手的编号。
样例输入
2 4 2
7 6 6 7
10 5 20 15
样例输出
1
两种java代码解决
1、每轮比赛得出新的积分后通过冒泡排序或快速排序得出新的排名(一维数组存储选手信息)
package xpc.sort; import java.util.Scanner; /**
* 瑞士轮问题实现
*
* @author xpc
*
*/
public class RuiShiLun { public static void main(String[] args) {
RuiShiLun obj = new RuiShiLun();
int no[];//每个选手的编号,顺序按名次
int s[];
int w[];
Scanner scanner = new Scanner(System.in);
System.out.println("请输入N R Q");
String str = scanner.nextLine();
String [] temp = str.split(" ");
int n = Integer.parseInt(temp[0]);
int r = Integer.parseInt(temp[1]);
int q = Integer.parseInt(temp[2]);
no = new int[2*n];
s = new int[2*n];
w = new int[2*n];
System.out.println("请输入对应编号选手初始分数:");
str = scanner.nextLine();
temp = str.split(" ");
for(int i = 0; i < temp.length;i++){
s[i] = Integer.parseInt(temp[i]);
no[i] = i+1;
}
System.out.println("请输入对应编号选手实力值:");
str = scanner.nextLine();
temp = str.split(" ");
for(int i = 0; i < w.length;i++){
w[i] = Integer.parseInt(temp[i]);
}
// int no[] = new int[]{1,2,3,4};//每个选手的编号,顺序按名次
// int s[] = new int[]{7,6,6,7};
// int w[] = new int[]{10,5,20,15};
// int n = 2;
// int r = 4;
// int q = 2;
int i = 0;
while(i < r){
i++;
System.out.println("第"+i+"轮比赛后:");
obj.sigleAfter(no,s,w);
for(int t = 0 ; t < s.length;t++){
System.out.println("第"+(t+1)+"名:"+no[t]+",分数:"+s[t]);
}
}
System.out.println("第"+r+"轮后排名第"+q+"的编号是:"+no[q-1]);
} public void sigleAfter(int no[],int s[],int w[]){
for(int i = 0; i < s.length-1; i+=2){
if(w[i] > w[i+1]){
s[i] ++;
}else{
s[i+1]++;
}
}
//选择排序
// chosesort(s, no, w);
//快排
quicksort(s,no,w,0,s.length-1);
} public void chosesort(int s[],int []no,int w[]){
for(int i = 0; i < s.length-1; i++){
for(int j = i+1; j< s.length;j++){
if(s[i] < s[j]){
int temp = s[i];
s[i] = s[j];
s[j] = temp; temp = no[i];
no[i] = no[j];
no[j] = temp; temp = w[i];
w[i] = w[j];
w[j] = temp;
}else if(s[i] == s[j]){
if(no[i] > no[j]){
int temp = s[i];
s[i] = s[j];
s[j] = temp; temp = no[i];
no[i] = no[j];
no[j] = temp; temp = w[i];
w[i] = w[j];
w[j] = temp;
}
}
}
}
} /**
* 三分取中值策略
* @param left
* @param right
* @return
*/
public int median3(int s[],int []no,int w[],int left,int right){
int center = (left+right)/2;
if(s[left] < s[center]){
swapReference(no,s,w, center, left);
}
if(s[center] < s[right]){
swapReference(no,s,w, right, center);
}
if(s[left] < s[center]){
swapReference(no,s,w, left, center);
}
if(left+1 > right){
swapReference(no,s,w, center, right);
}
return s[right];
} public void quicksort(int []s,int no[],int w[],int left,int right){
if(left < right){
int pivot = median3(s,no,w,left,right);
if(right - left > 1){
int i = left;
int j = right;
while(true){//大的放左边,小的放右边
while(s[++i] > pivot){
if(s[i] == pivot && no[i] >= no[right]){//积分相同,i的编号较大所以需要移到右边
break;
}
}
while(s[--j] <= pivot){
if(s[j] == pivot && no[j] <= no[right]){//积分相同,i的编号较小所以需要移到左边
break;
}
}
if(i < j){
swapReference(s,no,w, i, j);
}else{
break;
}
}
swapReference(s,no,w, i, right);
quicksort(s,no,w, left,i-1);
quicksort(s,no,w, i+1, right);
} }
} /**
* 互换数组中的元素
* @param a
* @param i
* @param j
*/
private void swapReference(int []no ,int []s,int w[],int i,int j){
int temp = no[i];
no[i] = no[j];
no[j] = temp; temp = s[i];
s[i] = s[j];
s[j] = temp; temp = w[i];
w[i] = w[j];
w[j] = temp;
} }
2、除第一次排序通过快速排序将积分重排,后面每轮将选手分为胜者组合败者组两组,通过归并合在一起(二维数组存储选手信息)
package xpc.sort; public class RuiShiLun2 { public static void main(String[] args) {
RuiShiLun2 sort = new RuiShiLun2();
int n = 2;
int r = 4;
int q = 2;
// int no[] = new int[]{1,2,3,4};//每个选手的编号,顺序按名次
// int s[] = new int[]{7,6,6,7};
// int w[] = new int[]{10,5,20,15};
int ans [][] = new int[2*n][3];//0:积分 1:实力 2:编号
ans[0][0] = 7;
ans[0][1] = 10;
ans[0][2] = 1; ans[1][0] = 6;
ans[1][1] = 5;
ans[1][2] = 2; ans[2][0] = 6;
ans[2][1] = 20;
ans[2][2] = 3; ans[3][0] = 7;
ans[3][1] = 15;
ans[3][2] = 4;
int a[][] = new int [n][3];//胜者组
int b[][] = new int [n][3];//败者组 sort.sigleAfter(a, b, ans); int r1 = 1;
sort.chosesort(ans);
System.out.println("第"+r1+"轮后排名");
for(int i = 0 ; i < ans.length;i++){
System.out.println("第"+(i+1)+"名:"+ans[i][2]+"-"+ans[i][0]+"-"+ans[i][1]);
}
while(r > 1 && r1 <r){
r1++;
sort.sigleAfter(a, b, ans);
sort.mergeArray(a, b, ans);
System.out.println("第"+r1+"轮后排名");
for(int i = 0 ; i < ans.length;i++){
System.out.println("第"+(i+1)+"名:"+ans[i][2]+"-"+ans[i][0]+"-"+ans[i][1]);
}
}
System.out.println("第"+r+"轮后排名第"+q+"的编号是:"+ans[q-1][2]);
}
private void sigleAfter(int a[][],int b[][],int ans[][]){
int j = 0;
for(int i = 0; i < ans.length-1; i+=2){
if(ans[i][1] > ans[i+1][1]){
ans[i][0]++;
a[j] = ans[i];
b[j] = ans[i+1];
}else{
ans[i+1][0]++;
a[j] = ans[i+1];
b[j] = ans[i];
}
j++;
}
} /**
*
* 选择排序
* @param s
* @param no
* @param w
*/
public void chosesort(int ans[][]){
for(int i = 0; i < ans.length-1; i++){
for(int j = i+1; j< ans.length;j++){
if(ans[i][0] < ans[j][0]){
int[] temp = ans[i];
ans[i] = ans[j];
ans[j] = temp; }else if(ans[i][0] == ans[j][0]){
if(ans[i][2] > ans[j][2]){
int []temp = ans[i];
ans[i] = ans[j];
ans[j] = temp;
}
}
}
}
} /**
* 胜者组败者组做归并
* @param a
* @param b
* @param ans
*/
private void mergeArray(int a[][],int b[][],int ans[][]){
int k = 0;
int t = 0;
int m = 0;
while(t<a.length && m<b.length){
if(a[t][0] > b[m][0]){
ans[k++] = a[t++];
}else{
if(a[t][0] == b[m][0] && a[t][2] < b[m][2]){
//积分相同编号小的往前排
ans[k++] = a[t++];
continue;
}
ans[k++] = b[m++];
}
}
while(t<a.length){
ans[k++] = a[t++];
}
while(m<b.length){
ans[k++] = b[m++];
}
}
}
[NOIP2011普及组]瑞士轮 JAVA实现的更多相关文章
- NOIP2011普及组 瑞士轮
OJ地址: https://www.luogu.org/problemnew/show/P1309 http://bailian.openjudge.cn/practice/4031/ 总时间限制: ...
- NOIP2011普及组 瑞士环 保序性
题目链接:http://noi.openjudge.cn/ch0401/4363/ 分析:如果直接模拟,时间复杂度是O(r*nlogn)超时 然后我们发现每次一轮开始时,刚开始是保序的,然后我们可以把 ...
- NOIP2011 普及组 T3 洛谷P1309 瑞士轮
今天题做太少,放道小题凑数233 题目背景 在双人对决的竞技性比赛,如乒乓球.羽毛球.国际象棋中,最常见的赛制是淘汰赛和循环赛.前者的特点是比赛场数少,每场都紧张刺激,但偶然性较高.后者的特点是较为公 ...
- [NOIP2011] 普及组
数字反转 小模拟 #include<cstdio> #include<iostream> #include<cstring> using namespace std ...
- NOIP2011普及组 数字反转
题目OJ链接: http://codevs.cn/problem/1130/ https://www.luogu.org/problemnew/show/P1307 2011年NOIP全国联赛普及组 ...
- 【解题报告】瑞士轮(NOIP2011普及组T3)
[题外话:这道题吧……说实话我不太喜欢……因为卡快排.] 题目不贴了,就是给你一个赛制,然后各个选手的初始得分和能力值,问你进行R轮比赛之后第Q名的编号是多少(这个编号读进来就要算OYZ,初始快排的时 ...
- 【单调队列】Vijos P1771 瑞士轮 (NOIP2011普及组第三题)
题目链接: https://vijos.org/p/1771 题目大意: 给定2N个人(N<=100 000)和其初始分数.能力值(能力两两不同),比赛M次(M<=50),每次PK都是按分 ...
- noip2011普及组——统计单词数
统计单词数 时间限制:1 s 内存限制:128MB [问题描述]一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数.现在,请你编程实 ...
- noip2011普及组——数字反转
数字反转 时间限制:1s 内存限制:128MB[问题描述]给定一个整数,请将该数各个位上数字反转得到一个新数.新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零 ...
随机推荐
- zabbix 配置
终于把zabbix配置好了.可能还有待优化 我主要参考了几个链接 http://lnmp.org/install.html 一键安装lnmp http://blog.unix178.com/2 ...
- Fedora 17 修改GRUB启动菜单顺序
Fedora 16采用GRUB2,因此启动菜单编辑方式与以前版本有所不同 设置默认启动Windows 1. 首先找到Windows的menuentry # cat /boot/grub2/grub ...
- php内存申请和销毁
内存申请 ZendMM使用自身heap层申请内存追踪结果: ZEND_ASSIGN_SPEC_CV_CONST_HANDLER (......) -> ALLOC_ZVAL(......) -& ...
- win7如何完全写在iis
在前些天,因为需要搭建了ftp服务器,但是今天不需要了,所以要卸载iis,因为我不会让iis和apache同时共存,所以只能卸载了 先找到windows功能,然后把Internet信息服务勾选掉,重启 ...
- Python的面向对象3
接下来,我们接着讲Python的面向对象,在上一次的博客中,我们详细介绍了类与对象的属性,今天,我们来详细介绍一下面向对象中的方法! 1.定义实例方法 一个实例的私有属性就是以__开头的属性,无法被外 ...
- VS2013发布web项目到IIS上遇到的问题总结
vs2010发布网站到本地IIS的步骤 http://blog.csdn.net/cx_wzp/article/details/8805365 问题一:HTTP 错误 403.14 - Forbid ...
- SVN - 配置
版本控制器 1.创建文件夹 svn 2.打开终端 进入该文件夹 3.输入 svnadmin 如果有错 xcrun: error: active developer path ("/Appli ...
- VBA在EXCEL中创建图形线条
EXCEL使用了多少行: ActiveSheet.UsedRange.Rows.Count(再也不用循环到头啦) 创建线条并命名:ActiveSheet.Shapes.AddLine(x1,y1,x2 ...
- aspx、ashx以及cs的关系,viewState
aspx和ashx关系:aspx就是一种特殊的ashx,aspx对应的类是page,它是实现了IHttpHandler接口,所以说aspx是高级的HttpHandler.aspx中帮我们封装了很多操作 ...
- poj 1132
暑假集训做的第一个题,模拟,挺简单的,不过要细心点... 没什么好说的,直接贴代码: #include<cstdio> #include<cstring> using name ...