H Counting 模拟

 

 有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;
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值