lahlahblog喵~

AtCoder Regular Contest 105

lahlah·2021-12-22 21:39·59 次阅读

AtCoder Regular Contest 105

在这里插入图片描述
菜的真实
T3,T4卡大题还行

C - Camels and Bridge#

首先看数据范围肯定不是一个多项式复杂度的算法

考虑枚举全排列,那么怎么判断头尾最短的长度是多少呢?

其实也不难,只要把每个连续段开到必须要开长度,然后大的继承小的即可

具体实现可以看代码

code:

Copy
#include<bits/stdc++.h> using namespace std; const int N = (1 << 8) + 5; int n, m, a[15], sum[N], g[N], f[15], id[15]; int main() { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i ++) scanf("%d", &a[i]); sort(a + 1, a + 1 + n); for(int S = 0; S < (1 << n); S ++) for(int i = 1; i <= n; i ++) if((S >> (i - 1)) & 1) sum[S] += a[i]; while(m --) { int l, s; scanf("%d%d", &l, &s); if(s < a[n]) { printf("-1"); return 0; } for(int S = 0; S < (1 << n); S ++) if(sum[S] > s) g[S] = max(g[S], l); } for(int i = 1; i <= n; i ++) id[i] = i; int ans = 1e9; do { for(int i = 1; i <= n; i ++) f[i] = 0; for(int i = 1; i <= n; i ++) { int S = (1 << (id[i] - 1));; for(int j = i + 1; j <= n; j ++) { S |= (1 << (id[j] - 1)); f[j] = max(f[j], f[i] + g[S]); } } ans = min(ans, f[n]); } while(next_permutation(id + 1, id + 1 + n)); printf("%d", ans); return 0; }

D - Let's Play Nim#

可以看出来要满足全部移到盘子后,最后一个人要尽量让盘子上的抑或和为0,否则下一个人必胜

那么如果n为奇数,最后一次移动一定是先手,那么后手只需要瞎捣乱,把一半以上的叠到一个上面就行了所以后手必赢

如果n为偶数,如果可以对称的放(即每个数出现次数都是偶数次)那么后手必胜,否则先手必胜

code:

Copy
#include<bits/stdc++.h> #define N 200050 using namespace std; int n, a[N]; void solve() { scanf("%d", &n); for(int i = 1; i <= n; i ++) scanf("%d", &a[i]); if(n & 1) { printf("Second\n"); return ; } sort(a + 1, a + 1 + n); //for(int i = 1; i <= n; i ++) printf("%d ", a[i]); printf("\n"); for(int i = 2; i <= n; i += 2) if(a[i] != a[i - 1]) { printf("First\n"); return ; } printf("Second\n"); } int t; int main() { scanf("%d", &t); while(t --) solve(); return 0; }

E - Keep Graph Disconnected#

又是博弈
如果

贺一发杨队的分析
在这里插入图片描述
code:

Copy
#include<bits/stdc++.h> #define N 200050 using namespace std; int vis[N], n, m, gs; vector<int> g[N]; void dfs(int u) { if(vis[u]) return ; gs ++; vis[u] = 1; for(int v : g[u]) dfs(v); } void solve() { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i ++) g[i].clear(), vis[i] = 0; for(int i = 1; i <= m; i ++) { int u, v; scanf("%d%d", &u, &v); g[u].push_back(v), g[v].push_back(u); } if(n & 1) { if((1ll * n * (n - 1) / 2 - m) & 1) printf("First\n"); else printf("Second\n"); return ; } gs = 0; dfs(1); int s = gs; gs = 0; dfs(n); int ss = gs; if((s + ss) & 1) { printf("First\n"); return ; } if((1ll * n * (n - 1) / 2 - 1ll * s * ss - m % 2) & 1) printf("First\n"); else printf("Second\n"); } int t; int main() { scanf("%d", &t); while(t --) solve(); return 0; }
posted @   lahlah  阅读(59)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示
目录