直接模拟
模拟代码
#include<iostream>
#include<cstdio>
#define ll unsigned long long//不开long long 见祖宗
using namespace std;
ll k;
int n,a[510][510];
int u,v,t;
int main()
{
cin>>n>>k;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>a[i][j];
u=1;//u为批评者
v=2;//v为被批评者
for(int i=2;i<=k;i++)
{
t=v;
v=a[v][u];
u=t;
}//第v个人批评a[v][u]个人
//t用来辅助交换
cout<<u<<endl;
return 0;
}
周期循环
看数据范围:
1
≤
k
≤
1
0
18
1≤k≤10^{18}
1≤k≤1018
于是打表找规律
#include<iostream>
#include<cstdio>
#define ll unsigned long long
using namespace std;
ll k;
int n,a[510][510];
int u,v,t;
int main()
{
cin>>n>>k;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>a[i][j];
u=1;
v=2;
for(int i=2;i<=k;i++)
{
t=v;
v=a[v][u];
u=t;
cout<<v<<' '<<u<<endl;
}
return 0;
}
发现有规律!
上代码:
#include<iostream>
#include<cstdio>
#define ll unsigned long long
using namespace std;
ll k;
int n,a[510][510];
int s[510][510];//储存批评双方的出现位置
int u,v,t,len,c;
int main()
{
cin>>n>>k;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>a[i][j];
u=1;
v=2;
for(int i=2;i<=k;i++)
{
t=v;//模拟
v=a[v][u];
u=t;
if(s[v][u])//这个双方是否出现过
{
len=i-s[v][u];//周期长度
c=s[v][u];
break;
}
s[v][u]=i;//标记批评双方
}
if(c)//是否找到周期
{
len=(k-c)%len;//周期外的
for(int i=1;i<=len;i++)
{
t=v;//模拟
v=a[v][u];
u=t;
}
}
cout<<u<<endl;
return 0;
}