日常刷题2025-3-9

日常刷题2025-3-9

分配宝藏

2025钉耙编程(一)1007

思路:博弈论(分赃谜题)

https://www.bilibili.com/video/BV1g8411o7w2/?vd_source=4a339d299e165d8fe38b9926c5240eae

代码

#include <bits/stdc++.h>

typedef long long int64;

const int mod=1'000'000'007;

void work(){
  int n;
  std::cin>>n;
  n>>=1;
  std::cout<<1LL*n*(n+1)%mod<<'\n';
}

int main(){
  std::ios::sync_with_stdio(0);
  std::cin.tie(0);
  int T=1;
  std::cin>>T;
  for (;T--;) work();
  return 0;
}

P4568 [JLOI2011] 飞行路线

绿色

思路:分层图最短路

看题目范围发现 k 非常小,把它当作分层图的另一个状态完全可以接受

\(dis[i][j]\):表示到 i 这个点用了 j 次免费机会。使用Dijkstra有两种更新方式,分别不发生状态转换,和发生状态转换。

Dijkstra 的思路就是把一个状态所以能转移的状态全部加到堆中,后序再选择。

本题有个奇葩数据是不需要使用 k 次免费机会就达到最小值,需要注意。

经验+1

分层图最短路的题有两种思路:

  1. 层数非常少(只有两层)我们完全可以把图建出来然后跑普通的最短路
  2. 层数比较多,不能事先建图,只能在 Dijkstra 转移的时候把状态的转换考虑进去。

代码

#include <bits/stdc++.h>

typedef std::pair<long long, long long> pll;
typedef std::pair<int, int> pii;
#define INF 0x3f3f3f3f
#define MOD 998244353
using i64 = long long;
const int N = 1e5+5;

void solve(){
	int n, m, k; std::cin >> n >> m >> k;
	int st, ed; std::cin >> st >> ed;
	std::vector go(n, std::vector<pii>());
	for (int i = 0; i < m; i++){
		int u, v, w; std::cin >> u >> v >> w;
		go[u].push_back({v, w});
		go[v].push_back({u, w});
	}

	std::vector dis(n, std::vector<int>(k+1, INT_MAX));
	std::vector vis(n, std::vector<bool>(k+1));
	std::priority_queue<std::tuple<int,int,int>, std::vector<std::tuple<int,int,int>>, std::greater<>> q;
	dis[st][0] = 0;
	q.push({0, st, 0});
	while (!q.empty()){
		auto [_, cur, state] = q.top(); q.pop();
		if (vis[cur][state]) continue;
		vis[cur][state] = 1;

		for (auto [to, w] : go[cur]){
			if (dis[to][state] > dis[cur][state] + w){
				dis[to][state] = dis[cur][state] + w;
				q.push({dis[to][state], to, state});
			}
			if (state < k && dis[to][state+1] > dis[cur][state]){
				dis[to][state+1] = dis[cur][state];
				q.push({dis[to][state+1], to, state+1});
			}
		}
	}

	std::cout << (*std::min_element(dis[ed].begin(), dis[ed].end())) << '\n';
}

signed main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(2);
	int t = 1, i;
	for (i = 0; i < t; i++){
		solve();
	}
	return 0;
}

心得

以后打牛客周赛无脑开 long long 吧,直接祭出大杀器#define int long long。两个我觉得不会爆整形的题都被卡了,我艹了

posted @ 2025-03-09 14:43  califeee  阅读(18)  评论(0)    收藏  举报