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 | 询问的第二个人 |
返回值说明如下:
返回值 | 说明 |
---|---|
1 | a比b强 |
0 | a不比b强 |
-1 | 参数不合法,遇到这个时,请即时停止你的程序,你将获得Wrong Answer |
我们规定自己不比自己强。
输入描述
输入代码由系统帮助实现,我们约定人数 。
,表示人数。
接下来
行,每行包括
个整数good[i][j]
,如果其为
,表示
不比
强,如果其为
表示
比
强。
输出描述
-1
。
当你的答案正确且你询问的次数在标程的3倍
预设代码
前置代码
/* 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 */
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]);
// }