蓝桥杯备赛打卡Day6

蓝桥杯每日一题
(1)5369.棋盘
(2)4655.重新排序
(3)3745.牛的学术圈I
(4)1238.日志统计

以下是部分题目的代码

//棋盘(差分 | 异或运算)
const int N = 2010;
int n, m, a[N][N];

int main()
{
	ios::sync_with_stdio(false);
	cin >> n >> m;
	
	while (m--)
	{
		int x1, y1, x2, y2; cin >> x1 >> y1 >> x2 >> y2;
		a[x1][y1] ^=  1;
		a[x2 + 1][y1] ^=  1;
		a[x1][y2 + 1] ^= 1;
		a[x2 + 1][y2 + 1] ^=  1;
	}

	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
		{
			a[i][j] ^= a[i - 1][j];
			a[i][j] ^= a[i][j - 1];
			a[i][j] ^= a[i - 1][j - 1];
		}

	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= n; j++)
			cout << a[i][j];
		cout << endl;
	}

	return 0;
}
//重新排序
typedef long long ll;
const ll N = 100010;
ll n, m, a[N], s[N], b[N], sum1, sum2;

int main()
{
	ios::sync_with_stdio(false);
	cin >> n;
	for (ll i = 1; i <= n; i++)
	{
		cin >> a[i];
		s[i] = a[i] + s[i - 1];
	}

	cin >> m;
	while (m--)
	{
		ll l, r; cin >> l >> r;
		b[l] += 1, b[r + 1] -= 1;//构建差分
		sum1 += s[r] - s[l - 1];//重新排列前的总和
	}

	for (ll i = 1; i <= n; i++) b[i] += b[i - 1];//还原差分,得出每个元素被访问到的次数

	//对两数组进行排序,令数组大的元素出现在访问次数多的位置
	//进行排序后,索引越大,元素越大且访问次数越多
	sort(a + 1, a + 1 + n), sort(b + 1, b + 1 + n);
	
	for (ll i = 1; i <= n; i++) sum2 += a[i] * b[i];//重新排列后的总和

	cout << sum2 - sum1 << endl;

	return 0;
}
//日志统计
//数据相对复杂,看代码很容易懂,自己很难想出来,记得及时回顾
typedef pair<int, int> PII;
const int N = 100010;
PII logs[N];//记录时间和id
int cnt[N];//记录某个id的点赞数
bool st[N];//记录该id是否为热帖
int n, d, k;

int main()
{
	ios::sync_with_stdio(false);
	cin >> n >> d >> k;
	for (int i = 1; i <= n; i++)
	{
		int ts, id; cin >> ts >> id;
		logs[i] = { ts,id };
	}

	sort(logs + 1, logs + 1 + n);

	for (int l = 1, r = 1; r <= n; r++)
	{
		int ts = logs[r].first, id = logs[r].second;
		cnt[id]++;//给有记录的id的点赞数加一

		//关键:根据时间差移动指针
		while (logs[r].first - logs[l].first >= d)
		{
			cnt[logs[l].second]--;
			l++;
		}

		if (cnt[id] >= k) st[id] = true;//标记为热帖
	}

	//遍历所有id
	//这里不能遍历logs数组,因为有的id会重复,导致重复打印
	for (int id = 1; id <= 100000; id++)
		if (st[id]) cout << id << endl;

	return 0;
}
//牛的学术圈I
//解法一(双指针)
const int N = 100010;
int n, m, a[N];

bool cmp(int x,int y)
{
	return x > y;
}

int main()
{
	ios::sync_with_stdio(false);
	cin >> n >> m;
	for (int i = 1; i <= n; i++) cin >> a[i];

	sort(a + 1, a + 1 + n, cmp);//从大到小排序

	int idx = 0;
	//定义l和r,令位于[l,r]的元素相等
	for (int l = 1, r = 1; r <= n;r++)
	{
		if (a[r] != a[l]) l = r;//更新区间

		if (a[r] < r)
		{
			if (m == 0)
			{
				idx = r - 1;//记录索引
				break;
			}
			for (int i = l; i <= n && i <= l + m - 1; i++) a[i]++;//增加引用次数
			m = 0;//用光
			r--;//抵消r++,在下个循环中重新判断当前元素是否>=索引
		}

		if (r == n) idx = n;//全部元素都>=索引
	}

	cout << idx << endl;


	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值