6. 找大佬

1 题目描述

找大佬

成绩20开启时间2021年09月24日 星期五 18:00
折扣0.8折扣时间2021年11月15日 星期一 00:00
允许迟交关闭时间2021年11月23日 星期二 10:00

众所周知,每个专业里都会有一些大佬隐藏在人群里。软件工程专业也是如此。今天的你就像从人群中找到真正的大腿,找到这个大佬。

假设现在有 名同学(编号为 )在班级里,这里面可能存在最多一名大佬。大佬的定义如下:

  • 他比其他 个人都强

  • 其他 ​个人都不比他强

我们假设强的关系不一定是绝对的(可能出现我比你强,你也比我强的情况),也不具有传递性(a比b强,b比c强,a不一定比c强),现在给你提供了int better(int a, int b)函数,该函数的参数含义如下:

参数说明
a询问的第一个人
b询问的第二个人

返回值说明如下:

返回值说明
1a比b强
0a不比b强
-1参数不合法,遇到这个时,请即时停止你的程序,你将获得Wrong Answer

我们规定自己不比自己强。

你要尽可能少的调用better函数来解决此问题,来找出真正的大佬。

输入描述

输入代码由系统帮助实现,我们约定人数

输入第一行包括一个整数 ,表示人数。

接下来 行,每行包括 个整数good[i][j],如果其为 ,表示 不比 强,如果其为 表示 强。

输出描述

你需要在你的函数里输出你找到的大佬,如果你没有找到,输出-1

接下来将由系统输出你的询问记录。

当你的答案正确且你询问的次数在标程的3倍以内时,你将AC此题。

预设代码

前置代码
/* PRESET CODE BEGIN - NEVER TOUCH CODE BELOW */

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1005;
int n;
bool good[maxn][maxn];
void guessdalao(int n); // you should finish this
int better(int a, int b)
{
if (a <= 0 || a > n || b <= 0 || b > n) return -1;
return good[a][b];
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
{
int t;
scanf("%d", &t);
good[i][j] = t;
}
guessdalao(n);
return 0;
}
/*
void guessdalao(int n)
{
// finish this
}
*/

/* PRESET CODE END - NEVER TOUCH CODE ABOVE */

 测试输入 期待的输出 时间限制 内存限制 额外进程
测试用例 1以文本方式显示
  1. 2↵
  2. 0 0↵
  3. 1 0↵
以文本方式显示
  1. 2↵
  2. 3↵
  3. 2 1↵
  4. 1 2↵
  5. 2 1↵
1秒153600KB0

2 代码

#include <bits/stdc++.h>  
using namespace std;  
const int maxn = 1005;  
int n;  
bool good[maxn][maxn];  
void guessdalao(int n); // you should finish this  
int better(int a, int b)  
{  
    if (a <= 0 || a > n || b <= 0 || b > n) return -1;  
    return good[a][b];  
}  
int main()  
{   
    freopen("file in.txt","r",stdin);
    scanf("%d", &n);  
    for (int i = 1; i <= n; i++)  
        for (int j = 1; j <= n; j++)  
        {  
            int t;  
            scanf("%d", &t);  
            good[i][j] = t;  
        }  
    guessdalao(n);  
    return 0;  
}


/* 
二分法,每次取两个出来比较,把强者下标存入新的数组,不断重复,直到只剩下一个人,注意奇数时 log2n
把这个强者再和每个人比较一下,确认比每个人强,没人比他强
*/ 
void guessdalao(int n){
    int stronger[n];
    int newdata[n];  //用来存储筛选出来的新的强者的下标,待会用来新一轮的筛选
    int i;
    int k; //遍历stronger
    int n0=n; //防止改动n
    int cmpans,cmpans1;
    int flag=1;// 不是大佬的标志

    for(i=0;i<n;i++){
        newdata[i] = i+1;
    }

    //那个强者表里面下标是从1开始的
    while(1){
        /*
        // 错误的把筛选出来的数据和原来的数据进行比较,导致了错乱,应该建立数组把每一次新数据存进去
        for(i=0,k=0;i<n0-1;i+=2){
            cmpans = better(i+1,i+2);
            if(cmpans==-1){
                return;
            }
            if(cmpans==1){
                stronger[k]=i+1;//把强者的下标存进去
                k++;
            }
            if(cmpans==0){
                stronger[k]=i+2;//把强者的下标存进去
                k++;
            }

        }
        */

       for(i=0,k=0;i<n0-1;i+=2){
           cmpans = better(newdata[i],newdata[i+1]);
           if(cmpans==-1){
                return;
            }
            if(cmpans==1){
                stronger[k]=newdata[i];//把强者的下标存进去
                k++;
            }
            if(cmpans==0){
                stronger[k]=newdata[i+1];//把强者的下标存进去
                k++;
            }
       }
        //奇数的情况
        if(n0%2==1){
            //这时候i刚好等于n-1;
            stronger[k]=newdata[i];
            k++;
        }
        n0 = k;
        if(n0==1){
            break;//只剩下一个人的时候退出循环
        }
        for(i=0;i<n0;i++){
            newdata[i] = stronger[i];
        }
    }

    for(i=0;i<n;i++){
        if(stronger[0]==i+1){
            continue;/// 遇到自己不比较
        }
        cmpans = better(stronger[0],i+1);
        cmpans1 = better(i+1,stronger[0]);
        if(cmpans!=1||cmpans1!=0){
            flag=0;
            break;
        }
    }
    if(flag==0){
        //找出来的不是大佬,就是说没有大佬
        cout<<"-1"<<endl;
    }
    if(flag==1){
        cout<<stronger[0]<<endl;
    }

}  

// void guessdalao(int n)    
// {    
//     int mate[n],i,j,k,l,m,choose[n];   
//     int temp,addtemp;   
//     int n0=n,n1=n,flag=1;    
//     for(i=0;i<n;i++)  mate[i]=i+1; //record the mate   
   
//     while(1)   
//     {   
//         for(j=1,k=0;j<n1;j+=2,k++)   
//         {   
//             temp=better(mate[j-1],mate[j]);   
//             if(temp==1) choose[k]=mate[j-1];  //choose the stronger   
//             if(temp==0) choose[k]=mate[j];  
//          //printf("%d,%d,%d\n",k,j,choose[k]) ; 
//         }     
           
//         if(n1%2==1)    
//         {   
//             choose[k]=mate[n1-1];    
//             k=k+1;   
//         }                   //remain the odd number  
//         n1=k;   
//         for(l=0;l<n1;l++) mate[l]=choose[l]; //remain stronger ones    
//         if(n1==1) break;   
//     }   
//     //("%d\n",mate[0]);   
//     for(m=1;(m<n0+1)&&(flag==1);m++)   //compare the one who wins with all the orignal mate   
//     {   
//         if(mate[0]==m) continue;   
//         temp=better(mate[0],m);   
//         addtemp=better(m,mate[0]);   
//         if((temp!=1)||(addtemp!=0))   
//         {   
//             flag=0;   
//             //printf("02\n");   
//             break;   
//         }   
//     }   
//     if(flag==0) printf("-1\n");   
//     if(flag==1) printf("%d\n",mate[0]);         
// }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
题目描述 小B是一名程序员,他每天都会刷题、写代码、学习新技术。小B很努力,他每天都会写下当天的总结和计划,并且为了养成良好的习惯,他决定将这些总结和计划打印出来挂在墙上,以便时刻提醒自己。但是小B很懒,他不想每天都手动地打印,于是他想写一个程序来自动化这个过程。 小B的要求很简单,他希望能够输入一个日期,然后程序会自动打印出从那一天开始到现在为止的每一天的总结和计划。其中,每日的总结和计划中,他会用若干个字符串来描述当天发生的事情、当天的心情、当天的计划等信息。 小B希望能够通过这个程序来监督自己的学习进度和每天的努力程度,希望你能够帮助他实现这个程序。 输入格式 第一行是一个整数n,表示小B的总结和计划的天数。 接下来n行,每行包含一个日期和一个字符串,用空格隔开。日期的格式是dd/mm/yyyy,字符串中可能包含空格,长度不超过100个字符。 输出格式 输出从输入的第一天到最后一天,每一天的总结和计划。每行输出一个日期和对应的字符串,用空格隔开。日期的格式是dd/mm/yyyy。 如果某一天没有总结和计划,则输出“None”。 样例输入 5 01/01/2020 Today is the first day of 2020! 02/01/2020 I learn a new skill today. 03/01/2020 I am in a bad mood today. 05/01/2020 I am too tired today, so I didn't do anything. 07/01/2020 I have a lot of plans for this week! 样例输出 01/01/2020 Today is the first day of 2020! 02/01/2020 I learn a new skill today. 03/01/2020 I am in a bad mood today. 04/01/2020 None 05/01/2020 I am too tired today, so I didn't do anything. 06/01/2020 None 07/01/2020 I have a lot of plans for this week! 注意事项 日期保证合法。 数据范围:1≤n≤1000
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值