题目描述
有 n n n 个人互相批评。
另提供矩阵 A A A。
规则如下:
-
第一次,第 1 1 1 个人批评第 2 2 2 个人。
-
如果第 i − 1 i-1 i−1 次为第 u u u 个人批评第 v v v 个人,
那么第 i i i 次为第 v v v 个人批评第 A v , u A_{v,u} Av,u 个人。
求第 k k k 次是谁进行批评(注意:不是被批评)。
输入格式
第一行:两个正整数, n n n 和 k k k。
以下 n n n 行:矩阵 A A A。矩阵的主对角线(就是从左上到右下的那条对角线)全是 0 0 0,其他部分由从 1 1 1 到 n n n 的正整数组成。
输出格式
一行:你的答案。
样例 #1
样例输入 #1
2 4
0 2
1 0
样例输出 #1
2
样例 #2
样例输入 #2
3 7
0 3 2
3 0 3
2 1 0
样例输出 #2
1
样例 #3
样例输入 #3
4 7
0 4 3 2
4 0 4 1
2 1 0 1
3 2 3 0
样例输出 #3
3
提示
数据范围
- 对于 35 p t s 35 pts 35pts 的数据,保证 1 ≤ k ≤ 1 0 5 1\leq k\leq 10^5 1≤k≤105。
- 对于所有的数据, 2 ≤ n ≤ 500 2\leq n\leq 500 2≤n≤500 且 1 ≤ k ≤ 1 0 18 1\leq k\leq 10^{18} 1≤k≤1018。
说明
题目译自 COCI2019-2020 CONTEST #5 T2 Političari ,译者 90693。
解题思路
利用暴力可以过一般的样例,通过枚举可以找到图中的环,进而减少操作次数
代码实现
#include<iostream>
using namespace std;
const int N=510;
int s[N][N];
int st[N][N];
long long n,k;
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++) //存图
for(int j=1;j<=n;j++)
cin>>s[i][j];
int a=1,b=2,t;
int mid=0;
k--;
while(k--){ //找环
mid++;
t=a;
a=b;
b=s[b][t];
if(st[a][b]){
mid=mid-st[a][b];
break;
}else{
st[a][b]=mid;
}
}
if(k>0){ //判断是否有环
k%=mid;
while(k--){
t=a;
a=b;
b=s[b][t];
}
}
cout<<a<<endl;
return 0;
}