目录
题目描述
有 n
个宝藏堆,每个宝藏堆有 m
个宝藏位置。对于每个宝藏位置,有两个属性:是否为有效宝藏(用 flag
表示,1
表示是有效宝藏,0
表示无效)以及一个价值 x
。现在给定一个初始的宝藏位置索引 k
,需要依次对每个宝藏堆进行操作,最后输出总价值对 20123
取模的结果。操作规则如下:
- 对于每个宝藏堆,将当前位置的价值
x
累加到总价值s
中,并对20123
取模。 - 更新当前位置的价值
x
为(x - 1) % sum + 1
,其中sum
是该宝藏堆中有效宝藏的数量。 - 从当前位置开始,按顺时针方向遍历宝藏堆,找到第
x
个有效宝藏的位置,更新当前位置为该位置。
输入数据从文件 treasure.in
中读取,最终结果输出到文件 treasure.out
中。
输入格式
第一行包含两个整数 n
和 m
,分别表示宝藏堆的数量和每个宝藏堆中宝藏位置的数量。
接下来的 n
行,每行包含 2 * m
个整数,每两个整数为一组,分别表示 flag
和 x
。
最后一行包含一个整数 k
,表示初始的宝藏位置索引。
输出格式
输出一个整数,表示总价值对 20123
取模的结果。
示例
输入
2 3
1 10 0 20 1 30
1 40 1 50 0 60
1
输出
50
解释:
- 初始
k = 1
。 - 对于第一个宝藏堆:
- 当前位置
k = 1
,x[1][1] = 20
,将20
累加到s
中,s = 20
。 sum[1] = 2
,更新x[1][1] = (20 - 1) % 2 + 1 = 0 % 2 + 1 = 1
。- 从位置
1
开始顺时针找第1
个有效宝藏,位置2
是有效宝藏,更新k = 2
。
- 当前位置
- 对于第二个宝藏堆:
- 当前位置
k = 2
,x[2][2] = 60
,将60
累加到s
中,s = (20 + 60) % 20123 = 80
。 sum[2] = 2
,更新x[2][2] = (60 - 1) % 2 + 1 = 1
。- 从位置
2
开始顺时针找第1
个有效宝藏,位置0
是有效宝藏,更新k = 0
。
- 当前位置
- 最终输出
s % 20123 = 80 % 20123 = 80
。
代码解析
cpp
#include<bits/stdc++.h>
using namespace std;
// flag 数组存储每个宝藏位置是否为有效宝藏,x 数组存储每个宝藏位置的价值
// s 存储总价值,n 为宝藏堆数量,m 为每个宝藏堆的宝藏位置数量
// i, j, k 为循环变量,sum 数组存储每个宝藏堆中有效宝藏的数量
int flag[10005][105],t,x[10005][105],s=0,n,m,i,j,k,sum[10005];
int main(){
// 从文件 treasure.in 读取输入,将输出写入文件 treasure.out
//freopen("treasure.in","r",stdin);
//freopen("treasure.out","w",stdout);
// 读取宝藏堆数量 n 和每个宝藏堆的宝藏位置数量 m
cin>>n>>m;
// 读取每个宝藏堆的宝藏信息
for(i=1;i<=n;i++){
for(j=0;j<m;j++){
// 读取当前位置的 flag 和 x
cin>>flag[i][j]>>x[i][j];
// 累加当前宝藏堆的有效宝藏数量
sum[i]+=flag[i][j];
}
}
// 读取初始宝藏位置索引 k
cin>>k;
// 依次处理每个宝藏堆
for(int i=1;i<=n;i++){
// 将当前位置的价值累加到总价值中,并对 20123 取模
s+=x[i][k]%20123;
s%=20123;
// 更新当前位置的价值
x[i][k]=(x[i][k]-1)%sum[i]+1;
// t 用于记录找到的有效宝藏数量
t=0;
// 从当前位置开始遍历
j=k;
while(1){
// 如果当前位置是有效宝藏,t 加 1
if(flag[i][j]==1)t++;
// 找到第 x[i][k] 个有效宝藏,跳出循环
if(t==x[i][k])break;
// 顺时针移动到下一个位置
j++;
// 如果超出范围,回到第一个位置
if(j==m)j=0;
}
// 更新当前位置
k=j;
}
// 输出总价值对 20123 取模的结果
cout<<s%20123;
return 0;
}
代码执行步骤
- 文件操作:使用
freopen
函数将标准输入和标准输出重定向到文件treasure.in
和treasure.out
(代码中注释掉了,可根据实际情况启用)。 - 读取输入:
- 读取
n
和m
。 - 循环
n
次,每次读取m
组flag
和x
,并计算每个宝藏堆的有效宝藏数量sum
。 - 读取初始位置索引
k
。
- 读取
- 处理每个宝藏堆:
- 累加当前位置的价值到
s
中,并对20123
取模。 - 更新当前位置的价值
x
。 - 从当前位置开始顺时针遍历,找到第
x
个有效宝藏的位置,更新k
。
- 累加当前位置的价值到
- 输出结果:输出
s
对20123
取模的结果。
复杂度分析
- 时间复杂度:O(nm),因为需要遍历每个宝藏堆,对于每个宝藏堆,最坏情况下需要遍历
m
个位置。 - 空间复杂度:O(nm),主要用于存储
flag
和x
数组。