直接模拟
模拟代码
#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;
}
本文探讨了一种涉及大规模指数级k值的周期性问题,通过代码优化从直接模拟转换到利用周期规律,从而显著提高了AC评测分数。作者分享了如何通过打表和数据结构分析找到解决方案,最终实现70分的高效率算法。
1000

被折叠的 条评论
为什么被折叠?



