题目来源:
Problem - B - Codeforceshttps://codeforces.com/contest/1602/problem/B
题干:
测试数据
INPUT
2
7
2 1 1 4 3 1 2
4
3 0
1 1
2 2
6 1
2
1 1
2
1 0
2 1000000000
OUTPUT
1
2
3
3
1
2
官方思路:
当步数大于n或者放缩到更小log(n)的时候,行为将会重复(待证明)
学长代码:
void solve() {
int n;
cin >> n;//sizeof array
vector<vector<int>>ans(n + 1, vector<int>(n));//定义一个二维数组,并且在第0行放置初始元素
for (auto& x : ans[0])
{
cin >> x;
}
for (int i = 1; i <= n; ++i)
{
vector<int> cnt(n + 1);
for (int j = 0; j < n; ++j)
{
++cnt[ans[i - 1][j]]; //cnt下标为数字,存入内容为对应下标的数字的个数
}
for (int j = 0; j < n; ++j)
{
ans[i][j] = cnt[ans[i - 1][j]];//将数字的个数存放给对应原数组中的对应数字的位置,
//中括号里为数字,这个数字对应到cnt的下标就是cnt里存放的数字个数,j代表数字在原数组的位置
}
}
int q;
cin >> q;
while (q--)
{
int x, k;
cin >> x >> k;
--x;
k = min(n, k);
cout << ans[k][x] << '\n';
}
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int T;
cin >> T;
for (int TwT = 1; TwT <= T; ++TwT)
{
solve();
}
return 0;
}
对应到本人的代码:
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
{
int a[2100];
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
int q;
cin >> q;
while (q--)
{
int x;
cin >> x;
int k;
cin >> k;
int b[2100];
int c[2100];
for (int j = 0; j < n; j++)
{
c[j] = a[j];
b[j] = a[j];
}
if (k == 0)
cout << a[x - 1] << endl;
if (k > 0)
{
if (k >n)
k = log(n);
while (k--)
{
int count = 0;
for (int j = 0; j < n; j++)
{
for (int i = 0; i < n; i++)
{
if (b[j] == b[i])
count++;
}
c[j] = count;
count = 0;
}
for (int j = 0; j < n; j++)
b[j] = c[j];
}
cout << b[x - 1] << endl;
}
}
}
}
本人的代码思路是不断遍历一个二维数组,来找到每个数字的个数,再存放入一个临时数组c。
因此当数据较多时,时间复杂度高。
每执行一次操作的复杂度为o(),因此tle。
对此可以采取学长代码的策略,将数字“存放”数组的下标中,将数字的个数作为内容放在对应下标的容器里。这样一来时间复杂度为o(n),不会出现tle情形。