首页 > 其他分享 >Acwing4244牛的比赛

Acwing4244牛的比赛

时间:2023-11-29 23:35:53浏览次数:47  
标签:java 比赛 int static Acwing4244 io import 奶牛

Acwing4244.牛的比赛

题目部分

N 头奶牛,编号 1∼N,一起参加比赛。

奶牛的战斗力两两不同。

这些奶牛之间已经进行了 M轮两两对决。

在对决中,战斗力高的奶牛一定会战胜战斗力低的奶牛。

请问,通过上述 M轮对决的结果,可以确定多少头奶牛的具体战斗力排名。

输入格式

第一行包含两个整数 N,M

接下来 M行,每行包含两个整数 a,b,表示奶牛 a 和奶牛 b 之间进行了对决,并且奶牛 a 战胜了奶牛 b

输出格式

输出可以确定具体战斗力排名的奶牛数量。

数据范围

1≤N≤100,
1≤M≤4500,
数据保证合法。

输入样例:

5 5
4 3
4 2
3 2
1 2
2 5

输出样例:

2

样例解释

2号奶牛输给了 1,3,4 号奶牛,战胜了 5 号奶牛,可以确定它的战斗力排名为 4。

5号奶牛输给了排在第 4 的 2 号奶牛,所以它的战斗力排名为 5。

其它奶牛不确定。

解法

首先这道题,虽然大佬们说是板子题,但是对我图论新手来说,这题还是相当有意思的!学到了很多!

错误解法

首先原先的我,是有点懵的,在看到这道题时,我们能够通过floyd得出这道题?我是怎么也想不出

我只能分析出某头牛的排名能确定下来,是因为它间接和其余的牛battle过

然后看了下大佬的题解(仅文字部分):

这是link,才做出了错误解法

还原下,我做出错误解法的思路哈:

我们可以把这些两头牛有没有间接比较过,转换为每个牛都是对应图中的节点,然后两点中可达,则为间接比较过

由此我通过转换关系把题目图化了,但是我不是添加单条有向边,而是添加了双向边

赋值为1的,代表着战胜

赋值为0的,代表着战败

想得很美好,由于对floyd算法运行流程不熟悉,导致误以为只要判断通过战败可达其余点或者战胜可达其余点即可,可是在floyd过程中,却是我们可以先通过战败边到另一个点,然后再由这个点选择战胜边接着刷新dist数组,导致算法有问题

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @author:天才玩家M
 * @date:2023/11/29 16:05
 * @description:TODO
 */
public class Main {
    static int n,m;
    static int N=110;
    static int INF=Integer.MAX_VALUE/4;
    static int [][]dist=new int[N][N];
    public static void floyd(){
        for (int k = 1; k <=n; k++) {
            for (int i = 1; i <=n; i++) {
                for (int j = 1; j <=n ; j++) {
                    dist[i][j]=Math.min(dist[i][j],dist[i][k]+dist[k][j]);
                }
            }
        }
    }
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String s = br.readLine();
        String[] s1 = s.split(" ");
        n = Integer.parseInt(s1[0]);
        m = Integer.parseInt(s1[1]);
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <=n; j++) {
                if(i==j){
                    dist[i][j]=1;
                }else{
                    dist[i][j]=INF;
                }
            }

        }
        for (int i = 0; i < m; i++) {
            s = br.readLine();s1 = s.split(" ");
            int a=Integer.parseInt(s1[0]);
            int b=Integer.parseInt(s1[1]);
            dist[a][b]=1;//代表可达且胜利
            //dist[b][a]=0;不能多出这一条,这只能是a->b单向的
            //不对上面的说法是错的,我们可以设置可达不过要与胜利有所区别
            dist[b][a]=0;//代表失败的可达,
            //想法很好,可是你有没有想过我们失败的点可以沿着失败的路线上去到达某个成功的点然后由成功的点再蔓延下去呢?
            //这种情况就违背了我们最初的意愿了,只让他们沿着成功之路或者失败之路而上,且我们只统计成功之路以及失败之路
            //2:可是这种情况下,如果夹杂成成功与失败,那我们又不会去统计!!!
            //那为什么正确答案为6而我们的为2呢?
            //解决了,答案浮出水面了,就是因为不去统计,假如1已经确定是倒数第一,而你唯一赢他的你又不算,那这不就少了吗?
        }
        floyd();
        int res=0;
        for (int i = 1; i <=n; i++) {
            int count1=0;
            int count=0;
            for (int j = 1; j <=n; j++) {
                if(dist[i][j]==0){
                    count1++;
                }
                else if(dist[i][j]!=INF){
                    count++;
                }
            }
            if(count==n||count1==n){
                res++;
            }
        }
        System.out.println(res);
    }
}

正确做法

大佬优雅地解决我一直困扰的战败与战胜,通过仅赋值单向边,而之后同时判断if(dist[i][j]<=INF/2||dist[j][i]<=INF/2),来确定这个对手是否交战过,并且由于仅赋值了战胜那一条,目前点要么战胜要么战败,而且看得比我的透彻,其实做出错误做法时,我就已经被要么战胜要么战败给迷惑了,

可是实际情况下是只要战过,无论成败即知排名(挺好想的,只要交手过,赢你的在前,输你的在后,你一定可以找到个位置).

至于INF/2是由于边比较多设定的,其他的也行

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @author:天才玩家M
 * @date:2023/11/29 20:38
 * @description:TODO
 */
public class Main1 {
    static int n,m;
    static int N=110;
    static int INF=Integer.MAX_VALUE/2;
    static int [][]dist=new int[N][N];
    public static void floyd(){
        for (int k = 1; k <=n; k++) {
            for (int i = 1; i <=n; i++) {
                for (int j = 1; j <=n ; j++) {
                    dist[i][j]=Math.min(dist[i][j],dist[i][k]+dist[k][j]);
                }
            }
        }
    }
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String s = br.readLine();
        String[] s1 = s.split(" ");
        n = Integer.parseInt(s1[0]);
        m = Integer.parseInt(s1[1]);
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <=n; j++) {
                if(i==j){
                    dist[i][j]=1;
                }else{
                    dist[i][j]=INF;
                }
            }

        }
        for (int i = 0; i < m; i++) {
            s = br.readLine();s1 = s.split(" ");
            int a=Integer.parseInt(s1[0]);
            int b=Integer.parseInt(s1[1]);
            dist[a][b]=1;
        }
        floyd();
        int res=0;
        for (int i = 1; i <=n; i++) {
          int count=0;
            for (int j = 1; j <=n; j++) {
                if(dist[i][j]<=INF/2||dist[j][i]<=INF/2){
                    count++;
                }
            }
            if(count==n){
                res++;
            }
        }
        System.out.println(res);
    }
}

标签:java,比赛,int,static,Acwing4244,io,import,奶牛
From: https://www.cnblogs.com/seamount3/p/17866133.html

相关文章

  • 模拟体育竞技分析:乒乓球比赛规则
     要求:1)模拟体育竞技分析:(不同学号选做不同题目,必做题)‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬......
  • NOIP 2023比赛报告
    第一题比赛情况$100$分,耗时$1$小时。题解对于$1\lei\len$,比较$w_i$字典序最小的字符$a_i$与每个$w_j(i\nej)$字典序最大的字符$b_j$。如果有$b_j\lea_i$,则$w_i$不能成为字典序最小的单词,反之可以。代码第二题比赛情况$100$分,耗时$2$小时。题解......
  • 【23秋】提高实战营 之 比赛篇
    2023提高实战营-秋专题测试01A.寇德佛斯题目链接A.寇德佛斯简要思路对于题目\(i\)和题目\(j\),假设当前开始了\(w\)时间,如果先做\(i\)再做\(j\),那么得到的分数将会是\(s_i-(w+t_i)·v_i+s_j-(w+t_i+t_j)·v_j\),最后整理一下可得时先做题目\(i\)......
  • 「比赛游记」NOIP 2023 游记
    「比赛游记」NOIP2023游记点击查看索引这是Index.百度百科扒的,有没有人给我来一张更好的.11.14(day998244350)模拟赛,稳定打挂.高二的明天信息学考,晚上看他们做题感觉很有趣味.但是初中有无聊的信息中考......
  • [NOIP2022] 比赛 - 总结
    [NOIP2022]比赛0.问题转化首先需要转化为区间历史和问题。具体上来讲,就是将询问离线后,扫描线维护对于\(r\)来说,每一个\(l\)的\(\sum_{i=l}^{r}(\max_{j=l}^{i}a_j\\cdot\\max_{j=l}^{i}b_j)\)那么答案就是区间和。1.构造信息与标记接下来就是如何维护区间历史和。......
  • 【比赛】2023 NOIP 备战
    2023NOIP备战考试策略20min左右通读题面(一定不要读错题,结合样例分析每道题题至少保证50pts左右的暴力不必按照顺序做题,那道题最有希望先做哪道随时存盘时间分配注重暴力(特别是没有思路的时候,有时间就打不要在没把握的的,耗费太长时间80pts-100pts都可以认......
  • 中睿天下荣获2023全国智能驾驶测试赛车联网安全比赛第一名
    9月24日,由工业和信息化部、公安部、交通运输部、中国科学技术协会、北京市人民政府共同主办的2023世界智能网联汽车大会展览会在北京闭幕。同期举行的全国智能驾驶测试赛(京津冀赛区)宣布比赛结果,中睿天下凭借过硬的产品实力,深厚的技术沉淀荣获车联网安全专项赛车联网实车靶场破解赛......
  • 【多校联考NOIP#12】比赛复盘
    A.星穹铁道读完题面就想到了\(O(n^2)\)的暴力。很好想,但是只有40分。观察到\(z_i=\pm1\),然而即便如此,我也没有得到有用的性质。(正解是用到这个性质的)然后我就暴力写了。正解的性质“最终在一个区间L,R内,初始也一定在一个连续段内”赛事没有想到。同时题解用了逆向思维,对......
  • P9740 「KDOI-06-J」ION 比赛 题解
    题目思路:先计算总分数\(sum\),\(c_i=\frac{100}{a_i}\)为每道题的每个测试点分数。如果总分数达到\(Au\)线,直接输出AlreadyAu.。否则计算到达\(Au\)线还需多少分\(p\),遍历所有题,求出每道题的失分,如果失分大于等于\(p\),则输出\(\lceil\frac{p}{c_i}\rceil\),即至......
  • 模拟3比赛报告
    比赛报告比赛名称:模拟赛\(3\)比赛时间:2023.8.22:00~5:00比赛过程今天再做题时,第一题明明很简单,但是因为没看清题目导致\([2~n-1]\)写成了for(inti=2;i<=n;i++)应该是for(inti=2;i<n;i++),导致扣除了\(80\)分;第二题因为自己读题不明白,导致运行错误就成为了\(0\)分......