现在经济不景气,经济危机席卷城市,很多人丢失了工作(你会
发现,和题目完全没关系)。
然而,锴锴找到了一个新工作,一个五星级宾馆„„的锁匠„„
的助理„„现在,锁匠总管要测验锴锴的能力。
锁匠总管给了锴锴 N 把钥匙,它们在一个大的钥匙环上,锁匠总
管把锴锴带到了一个神奇的房间里,里面有 N 扇们,显然,N 把钥匙
每个能开一扇门。总管给锴锴的任务就是打开这些门。锴锴将门编号成 1 到 N,
钥匙环上的钥匙从左到右编号为 1 到 N,
锴锴开门顺序为 1、2、3„„N,到了一扇门前,锴锴用最左边的钥
匙去开门,没打开的话就把最左边的钥匙通过环转到最右边,继续重
复上述操作,直到打开门为止,打开后,锴锴便继续到下一扇门。锴
锴为了显示自己的与众不同,硬是要开 T 次门,若开完了 N 扇门还没
到 T 次,锴锴便又回到第一扇门,把它关上,再打开„„(好无聊)
锴锴是一位好奇心很强的小盆友,现在,他想知道在开完全部门
后,他一共试错了多少次。
输入:
第一行两个整数,N(1<=N<=10 5 )和 T(1<=T<=10 9 )
第二行到第 N+1 行,第 i+1 行一个数 ai 代表第 i 号钥匙开 ai 号门
输出:
锴锴的试错次数
输入:
3 5
1
2
3
输出:
4
输入:
4 6
4
2
1
3
输出:
13
输入:
10 7
1
3
2
4
5
7
6
8
9
10
输出:
25
思路:
其实只要暴力跑第一遍,之后的会循环,取模数就ok了
#include <cstdio> #include <iostream> using namespace std; #define GC getchar() #define R register #define MAXN 100000+5 #define ll long long template <typename T> inline void read(T &x); int N,T,ans=0; int k[MAXN]; int d[MAXN]; ll sec[MAXN]; int main() { freopen("lock.in","r",stdin); freopen("lock.out","w",stdout); read(N),read(T); for(R int i=1;i<=N;i++) read(k[i]),d[k[i]]=i; // 存下门的位置 ll now=1,ans1=0; for(R int i=1;i<=N;i++) { ans1+=(d[i]+N-now)%N; now=d[i]; if(i==T) {printf("%lld\n",ans1);return 0;} }// 暴力跑一次 now=d[N];//记下最后一次的位置 for(R int i=1;i<=N;i++) { if(sec[i]==now) continue; sec[i]=sec[i-1];//继承 sec[i]+=(d[i]+N-now)%N; //跑 now=d[i]; } ll ans=ans1; ans+=(ll)(T/N-1)*sec[N]+sec[T%N]; printf("%lld\n",ans); return 0; } template <typename T> inline void read(T &x) { x=0;char a=GC;int f=1; for(;a>'9'||a<'0';a=GC) if(a=='-') f=-1; for(;a>='0'&&a<='9';a=GC) x=(x<<1)+(x<<3)+(a^48); x*=f; }