【2024.10.03】NOIP2024 赛前集训-刷题训练(5)

NOIP2017 提高组 小凯的疑惑

形式化题面:求最大的正整数 \(w\),满足 \(ax + by = w\) 不存在一对非负整数解。

第一眼想到 \(exgcd\),拿来分析一下:

因为 \(gcd(a,b) = 1\),所以 \(\forall w \in \mathbb{N^+}\) 肯定都有解,但不一定 \(x, y\) 都是非负整数。

接着容易发现,当其中一个未知数的解为 \(-1\) 时,\(w\) 可能就不满足条件。

但这个条件只是必要的。举个例子 :

\[3 \times 8 + 7 \times (-1) = 21 = 3 \times (8 - 7) + 7 \times(-1 + 3) = 3 \times 1 + 7 \times 2
\]

于是我们发现当 \(y = -1\) 时,\(w\) 满足题目条件当且仅当 $ x \lt b$。从 \(exgcd\) 的通解求法来讲,就是不能通过 \(x+kb, y -kb\) 来构造出一组非负整数解。

那么 \(w = a \times (b - 1) + b \times (-1) = a \times b - a - b\), 令 \(x = -1\) 推出来时一样的。

#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l);i<=(r);++i)
#define G(i,r,l) for(int i(r);i>=(l);--i)
using namespace std;
using ll = long long ;
ll a, b;
signed main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> a >> b;
cout << a * b - a - b << '\n';
return 0;
}

NOIP2017 提高组 时间复杂度

小模拟。把细节列出来认真写就好,耐得住性子总能找到缺陷调出来。

注意一下对时间复杂度的统计是遇到 F 就+ 1并更新 mx,遇到 E 就- 1。

借助 \(STL\) 可以省很多事。

#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l);i<=(r);++i)
#define G(i,r,l) for(int i(r);i>=(l);--i)
using namespace std;
using ll = long long ;
int T;
int len, num, cnte, cntf, mx;
stack<pair<char, int>> stk;
map<char, int> mp;
char omiga[10000], type[10000], name[10000], x[10000], y[10000];
int change(char *a){
if(a[0] == 'n') return 100000000;
int val = 0;
for(int i = 0; a[i]; ++i) val = val * 10 + a[0] - 48;
return val;
}
int solve(){
int ans = 2;
cin >> len >> omiga;
bool flag = 0;
int answer = 0;
num = 0;
cnte = 0;
cntf = 0;
mx = 0;
char stop = ' ';
mp.clear();
while(stk.size()) stk.pop();
for(auto x:omiga){
if(x == 'n') flag = 1;
if(isdigit(x)){
if(!flag) answer = 0;
else answer = answer * 10 + x - 48;
}
}
F(i, 1, len){
cin >> type;
if(type[0] == 'E'){
if(ans == -1) continue;
++cnte;
if(cnte > cntf) {
ans = -1;
continue;
}
char nw = stk.top().first;
int delta = stk.top().second;
stk.pop();
if(stop == nw) stop = ' ';
if(!isalpha(stop) && delta > 100) -- num;
mp[nw] = 0;
}
else{
++cntf;
cin >> name >> x >> y;
if(ans == -1) continue;
if(mp[name[0]] != 0) ans = -1;
int delta = change(y) - change(x) + 1;
mp[name[0]] = 1;
stk.emplace(name[0], delta);
if(isalpha(stop)) continue;
if(delta > 100) mx = max(mx, ++num);
if(delta <= 0) stop = name[0];
}
}
if(ans == -1 || cnte != cntf) return -1;
if(answer == mx) return 1;
return 0;
}
signed main(){
// freopen("ex_complexity2.in","r",stdin);
// freopen("complexity.out","w",stdout);
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> T;
while(T -- ){
int ans = solve();
if(ans == 1) cout << "Yes\n";
else if(ans == 0) cout << "No\n";
else cout << "ERR\n";
}
return 0;
}

NOIP2017 提高组 逛公园

第一步,找零环(小trick:先只连权值为 0 的边跑 \(tarjan\))。

第二步,跑 \(dijkstra\)。

第三步,建反图记忆化搜索方案数。

我们记 \(f[i][j]\) 表示 \(1\) 到 \(i\) 的路径长为 \(dis[i] + j\) 的最短路,对于边 \((v, u, w)\), 因为 \(dis[v] + w + j[v] = dis[u] + j[u]\), 即 \(j[v] = dis[u] + j[u] - w - dis[v]\), 有如下转移:

\[f[u][j] += f[v][dis[u] + j - w - dis[v]]
\]

注意初始化写完整,两张图的相关数组不要混用!

!!!自己疏忽的地方:\(f[1][0] = 1\), 但 \(f[1][k] = 0\) 不一定成立,因为可以从某个点绕回 \(1\), 这样 \(f[1][k]\) 就是有贡献的了。

积累 dp 统计方案的这个方法。(类似分层图)

#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l);i<=(r);++i)
#define G(i,r,l) for(int i(r);i>=(l);--i)
#define mk make_pair
#define fi first
#define se second
#define index iiiiidx
using namespace std;
using ll = long long ;
const int N = 2e5 + 5;
const ll inf = 0x3f3f3f3f3f3f3f3f;
struct cat{ int u, v, w; }edge[N << 1];
struct node{ int v, w, ne; }e[N << 2], g[N << 2]; ll dis[N], f[N][105];
bool vis[N];
priority_queue<pair<ll, int> >q; int first[N], idx = 0;
int head[N], index = 0; int dfn[N], low[N], scc[N], cnt = 0, num = 0;
bool ins[N];
stack<int> stk; int T, n, m, k, mod; void add(int x, int y, int z){ e[++idx] = (node){y, z, first[x]}; first[x] = idx; }
void ADD(int x, int y, int z){ g[++index] = (node){y, z, head[x]}; head[x] = index; }
void tarjan(int u, int f){
dfn[u] = low[u] = ++cnt, stk.emplace(u), ins[u] = 1;
for(int i = first[u];i ;i = e[i].ne){
int v = e[i].v;
if(!dfn[v]) tarjan(v, u),low[u] = min(low[u], low[v]);
else if(ins[v]) low[u] = min(low[u], dfn[v]);
}
if(low[u] == dfn[u]){
++num; int x, siz = 0;
do{ x = stk.top();
ins[x] = 0;
scc[x] = num;
stk.pop();
++siz;
}while(x != u);
if(siz == 1) scc[x] = 0, --num;
}
}
void dijkstra(int st){
while(q.size()) q.pop();
q.emplace(mk(0, st));
dis[st] = 0;
while(q.size()){
int u = q.top().se; q.pop();
if(vis[u]) continue;
vis[u] = 1;
for(int i = first[u]; i; i = e[i].ne){
int v = e[i].v, w = e[i].w;
if(dis[v] > dis[u] + w){
dis[v] = dis[u] + w;
q.emplace(mk(-dis[v], v));
}
}
}
}
ll dfs(int u, int k){
if(scc[u]) return -1;
if(u == 1 && k == 0) return f[u][k] = 1;
if(f[u][k] != -1) return f[u][k];
ll ret = 0;
for(int i = head[u]; i; i = g[i].ne){
int v = g[i].v, w = g[i].w;
ll tmp = dis[u] + k - w - dis[v];
if(tmp >= 0 && tmp <= k) {
int delta = dfs(v, tmp);
if(delta == -1) return -1;
(ret += delta) %= mod;
}
}return f[u][k] = ret;
}
void init(){
memset(dis, 0x3f, sizeof(dis));
memset(f, -1, sizeof(f));
memset(vis, 0, sizeof(vis));
memset(first, 0, sizeof(first)); idx = 0;
memset(head, 0, sizeof(head)); index = 0;
memset(dfn, 0, sizeof(dfn)); cnt = 0; num = 0;
memset(low, 0, sizeof(low));
memset(scc, 0, sizeof(scc));
memset(ins, 0, sizeof(ins));
if(stk.size()) stk.pop();
cin >> n >> m >> k >> mod;
F(i, 1, m){
int u, v, w;
cin >> u >> v >> w;
edge[i] = (cat){u, v, w};
if(w == 0) add(u, v, w), ADD(v, u, w);
}
F(i, 1, n) if(!dfn[i]) tarjan(i, 0);
}
int solve(){
F(i, 1, m){
int u = edge[i].u, v = edge[i].v, w = edge[i].w;
if(w != 0) add(u, v, w), ADD(v, u, w);
}
dijkstra(1);
ll ans = 0;
F(i, 0, k) {
ll delta = dfs(n, i);
if(delta == -1) return -1;
(ans += delta) %= mod;
}
return ans;
}
signed main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> T;
while(T--){
init();
cout << solve() << '\n';
}
return 0;
}

NOIP2017 提高组 奶酪

前置知识:球之间位置关系的判定依据:圆心距 与 半径和的关系。

下文用 “相切” 代指 “相切或相交”

算法1:并查集维护球之间的关系,\(O(Tn^2)\)。

算法2:先按 \(z\) 从小到大对所有圆心 \(a[i]\) 排序。另开一个数组 \(b\),若当前 \(a[i]\) 与 某个 \(b[j]\) 相切或者与下表面相切,就放进 \(b\) 里面。最后只需要判断是否存在 \(b[i]\) 与上表面相切就行。时间严格弱于 \(O(Tn^2)\)。

#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l);i<=(r);++i)
#define G(i,r,l) for(int i(r);i>=(l);--i)
#define int ll
using namespace std;
using ll = long long ;
const int N = 1005;
int T;
int n, h, r, btop = 0;
__int128 base;
__int128 pw(__int128 x){
return x * x;
}
struct node{
int x, y, z;
bool operator < (const node &o)const{
return z < o.z;
}
__int128 operator - (const node &o)const{
return pw(x - o.x) + pw(y - o.y) + pw(z - o.z);
}
}a[N], b[N];
inline bool check(int nw){
if(a[nw].z <= r) return 1;
F(i, 1, btop) if(a[nw] - b[i] <= base) return 1;
return 0;
}
signed main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> T;
while(T --){
btop = 0;
cin >> n >> h >> r;
base = 4 * r * r;
F(i, 1, n) cin >> a[i].x >> a[i].y >> a[i].z;
sort(a + 1, a + n + 1);
F(i, 1, n) if(check(i)) b[++ btop] = a[i];
bool tag = 0;
G(i, btop, 1) if(b[i].z >= h - r) {tag = 1; break;}
if(tag) cout << "Yes\n";
else cout << "No\n";
}
return 0;
}

【2024.10.03】NOIP2024 赛前集训-刷题训练(5)的更多相关文章

  1. 10.24afternoon清北学堂刷题班

    /* 这是什么题... */ #include<iostream> #include<cstdio> #include<cstring> #include<q ...

  2. NOIp2018停课刷题记录

    Preface 老叶说了高中停课但是初中不停的消息后我就为争取民主献出一份力量 其实就是和老师申请了下让我们HW的三个人听课结果真停了 那么还是珍惜这次机会好好提升下自己吧不然就\(AFO\)了 Li ...

  3. LeetCode的刷题利器(伪装到老板都无法diss你没有工作)

    在工程效率大行其道的今天,如果不会写点代码以后也不容易在测试圈混下去.今天给大家推荐一个LeetCode的刷题利器,可以伪装到连你老板在这里走过去都无法确认你是在干活呢,还是在干活呢. LeetCod ...

  4. 18.9.10 LeetCode刷题笔记

    本人算法还是比较菜的,因此大部分在刷基础题,高手勿喷 选择Python进行刷题,因为坑少,所以不太想用CPP: 1.买股票的最佳时期2 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. ...

  5. leecode刷题(10)-- 旋转图像

    leecode刷题(10)-- 旋转图像 旋转图像 描述: 给定一个 n × n 的二维矩阵表示一个图像. 将图像顺时针旋转 90 度. 说明: 你必须在原地旋转图像,这意味着你需要直接修改输入的二维 ...

  6. LeetCode刷题模板(1):《我要打10个》之二分法

    Author       :  叨陪鲤 Email         : vip_13031075266@163.com Date          : 2021.01.23 Copyright : 未 ...

  7. 牛客网NOIP赛前集训营-提高组(第四场)B题 区间

    牛客网NOIP赛前集训营-提高组(第四场) 题目描述 给出一个序列 a1, ..., an. 定义一个区间 [l,r] 是好的,当且仅当这个区间中存在一个 i,使得 ai 恰好等于 al, al+1, ...

  8. 10.1综合强化刷题 Day6

    T1 排序 题目描述 小Z 有一个数字序列a1; a2; .... ; an,长度为n,小Z 只有一个操作:选 定p(1<p<n),然后把ap 从序列中拿出,然后再插⼊到序列中任意位置. ...

  9. NOI Online 赛前刷题计划

    Day 1 模拟 链接:Day 1  模拟 题单:P1042 乒乓球  字符串 P1015 回文数  高精 + 进制 P1088 火星人  搜索 + 数论 P1604 B进制星球  高精 + 进制 D ...

  10. ZJOI2019一轮停课刷题记录

    Preface 菜鸡HL终于狗来了他的省选停课,这次的时间很长,暂定停到一试结束,不过有机会二试的话还是可以搞到4月了 这段时间的学习就变得量大而且杂了,一般以刷薄弱的知识点和补一些新的奇怪技巧为主. ...

随机推荐

  1. 【粉丝问答19】Linux内核中为啥变量没初始化就用了?你确定了解宏定义?

    @ 目录 一.问题 二.分析 三.宏定义的注意点 1. 只占用编译时间 2. 宏替换发生时机 3. 预处理包括哪些工作 四.如何快速展开复杂的宏定义? 第一步 第二步 五.练习 六.15个经典宏定义小 ...

  2. kubernetes批量删除evicted状态pod

    #!/bin/bash # get namespace namespaces=`kubectl get pod -A | grep -i "evicted" | awk '{pri ...

  3. Java微信授权登录小程序接口

    1.微信授权登录小程序的流程是什么 微信授权登录小程序的流程是一个涉及前端和后端交互的过程,主要目的是让用户能够使用微信账号快速登录小程序,避免重复输入用户名和密码.以下是该流程的详细步骤: 1.1前 ...

  4. .net相关知识点总结

    基础知识 [1]静态构造函数(执行一次,调用静态成员或实例化时执行一次) [2]抽象类和接口的区别 1:抽象类有字段,构造函数,非抽象方法(C#新版本接口可以定义方法体),接口没有 2:抽象类不可多继 ...

  5. PPT或Visio比较舒适的RGB配色参数

    1.187 204 235 2.222 156 83 3.117 156 83 4.64 116 52 5.117 121 74 6.69 137 148 7.182 194 154 8.207 19 ...

  6. redux开发中的一个小坑

    redux的actiontypes,不可以重名,重名将会报错 When called with an action of type "inserttoken", the slice ...

  7. CASIO fx-991CN X 使用

    复数转换 \(a+b \, {\mathrm i} \leftrightarrow r \angle \theta\) 进入复数运算模式 菜单 2 输入待转换数 OPTN ▼,选择目标格式. = 可通 ...

  8. Chrome扩展插件的开发--获取网页Cookies

    Chrome扩展插件的开发--获取网页Cookies Chrome浏览器在浏览器类应用软件中一直居于榜首,很多人选择Chrome浏览器不仅仅是因为它的稳定,还有它丰富的可拓展性.那么有没有想自己开发一 ...

  9. 【QT性能优化】QT性能优化之QT6框架高性能统计图框架快速展示百万个数据点曲线图

    QT性能优化之QT6框架高性能统计图框架快速展示百万个数据点曲线图 文章目录 百万个数据点的QT统计图运行效果 百万个数据点的QT统计图程序的源代码 QT统计图功能和效果展示 QT统计图模块整体结构 ...

  10. 官方 | 征集 Flutter 桌面端应用程序的构建案例

    亲爱的社区成员们,大家好! Google Flutter 团队希望了解开发者们使用 Flutter 构建的桌面端应用程序,以提高 Flutter 桌面端的测试覆盖率,邀请大家通过表单的形式提交征集和反 ...