前言:
代码不是本人写的,只是看讨论区有位大佬写了代码感觉很有道理(),试着理一理他的思路。
题目:
思路整理:
1.根据样例进行模拟
根据题目,我们分析出:两个人要在一天比赛的前提条件,a恰好想跟b比,b恰好想和a比,注意这里的想跟谁比是有顺序的,即a的预想对手比赛序列的第一个和b的预想对手比赛序列的第一个是互相选择的状态。
比如:在样例中
1:2 3
2:1 3
3:1 2
选手1和选手2在分别序列的第一个互相选择,所以第一天他们比,所以第一天比赛的是1和2
1:3
2:3
3:1 2
选手3和选手1属于互选状态,那么第二天比赛的是1和3
那么怎么定义这个互相选择状态呢?
这个时候就需要用哈希表的冲突了
2.哈希表和哈希值
使用unordered_set实现哈希表
C++ STL unordered_set容器完全攻略 (biancheng.net)
如何实现互相选择状态呢?
就是检测在该容器中是否存在这个值,用两个位置表示冲突,我们就使用一个函数,所以说我觉得关键实现的代码在于:
unordered_set<int> uset;
/*中间部分*/
int a=max(i,map[i][j]);
int b=min(i,map[i][j]);
int t=a*10000+b;
if(uset.find(t)!=uset.end())//发现冲突
{
//实现体
}
代码实现:
#include<bits/stdc++>
using namespace std;
#define long long int
#define 10005 maxn
#define int ll
int mp[1010][1010];
int cnt[1010];//每个参赛选手的比赛场数
signed main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>mp[i][j];
}
}
for(int i=1;i<=n;i++)
{
cnt[i]=1;
}
unordered_set<int> uset;
while(true)
{
int flag=0;
int day=0;//表示天数
for(int i=1;i<=n;i++)//遍历参赛选手
{
int j=cnt[i];
if(j>=n) continue;
int a=max(i,map[i][j]);
int b=min(i,map[i][j]);
int t=a*10000+b;
if(uset.find(t)!=uset.end())
{
if(flag==0)
{
res++;
flag=1;
}
cnt[i]++;
cnt[mp[i][j]]++;
}
else
{
uset.insert(t);
}
}
if(flag==0) break;
}
}