有k个人,k个人初始有一个位置。给出t的时间,每一个时间每个人有自己相应的移动。输出每个时间在同一个格子内的人数。
枚举时间然后将所有的人按对应的位移变动,统计重复人数即可。这个统计人数我当时没想到什么好方法,肯定是不能每个时间都两层循环遍历求,于是我想到了map,只需要更新每个人的位置然后删除原位置,最后遍历有人的点然后统计即可。但是我不是很理解map的常数,2000的数据量也超时了。
赛后看到一个很简洁的解法,我要统计人数,没必要遍历格子啊,直接从人数出发,哪个人在哪个格子这个格子的人就++,最后就能得到有人点的格子的总人数,得到这些格子的人数,再统计逆序对数就好做了。等差数列求和,但因为是由人来统计格子,每个人都会把这个格子的答案算一遍,所以和/n去重即可
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define int ll
#define mm(a) memset(a,0,sizeof(a))
const int N = 3e3 + 10;
const int mod = 998244353;
int T, n, m, k, q, t;
int vis[N];
int arr[N];
struct node {
int x, y;
}p[N];
char v[N][N];
int mp[N][N];
signed main() {
ios::sync_with_stdio(0); cin.tie(0);
cin >> n >> m >> k >> t;
for (int j = 1; j <= k; j++) {
int a, b;
cin >> p[j].x >> p[j].y;
}
for (int j = 1; j <= k; j++) {
cin >> v[j];
}
for (int j = 0; j <= t; j++) {
double ans = 0;
for (int i = 1; i <= k; i++) {
mp[p[i].x][p[i].y]++;
}
for (int j = 1; j <= k; j++) {
int n = mp[p[j].x][p[j].y];
ans +=(double)((n - 1) + ((double)(n - 1) * (n - 2) / 2))/n;//逆序对求和+去重
}
cout << ans << endl;
for (int i = 1; i <= k; i++) {
node tem = p[i];
mp[p[i].x][p[i].y] = 0;
if (v[i][j] == 'U')--p[i].x;
if (v[i][j] == 'L')--p[i].y;
if (v[i][j] == 'R')++p[i].y;
if (v[i][j] == 'D')++p[i].x;
}
}
}