【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. SpringBoot复习

    SpringBoot 开启事务:Application 加@EnableTransactionManagement ,Service方法加@Transaction 注解 注意:@Transaction ...

  2. 100ASK_IMX6ULL arm板子如何显示图片、汉字、划线、背景色

    最近在研究基于imx6ull开发板,想让开发板支持显示图片.字符串.背景色的功能. 操作的主要步骤如下: 移植设备树和驱动 移植libjpeg库 编写测试程序 一.移植设备树和驱动 开发板原厂SDK已 ...

  3. C语言中的短路现象

    短路现象1 比如有以下表达式 a && b && c 只有a为真(非0)才需要判断b的值: 只有a和b都为真,才需要判断c的值. 举例 求最终a.b.c.d的值. ma ...

  4. 华为交换机S5700-52C-EI开启telnet服务

    华为S5700交换机初始化和配置TELNET远程登录方法: 1,交换机开启Telnet服务 <Quidway>system-view #进入系统视图 [Quidway]telnet ser ...

  5. echarts x轴下绘制表

    效果图: 把下面代码复制到官网实例的js代码编辑中即可预览( 附连接:Examples - Apache ECharts) let map = { 销售单价: [2200.0,4000.9,700.0 ...

  6. GPT 中的函数调用(function call)是什么?

    在 OpenAI ChatGPT API 和 Google Gemini API 中我们可以看到函数调用的功能.这个功能是做什么用的?下面大概讲解. 以 Google Gemini API 函数调用 ...

  7. 传染病模型 SI

    参考了这篇写的很好的[1],讲了各种模型 因为是各种模型都是用微分方程写的,所以又去学习了一下微分方程 ,真的忘了有没有学过这个,反正一点印象也没有了. 好在[2] 这个文章又把我带回去了. SI 的 ...

  8. Spring Cloud集成Seata分布式事务-TCC模式

    参考文章 分布式事务实战方案汇总 https://www.cnblogs.com/yizhiamumu/p/16625677.html 分布式事务原理及解决方案案例https://www.cnblog ...

  9. P1543 [POI2004] SZP 题解

    P1543 [POI2004] SZP 题解 传送门. 题目简述 有 \(n\) 个人,每个人都会监视另一个人,要求选出尽可能多的同学,使得选出的每一名同学都必定会被监视到.且选出的同学不可再监视其他 ...

  10. RTThread内对##连接符和#转字符串这俩符号的使用

    早就知道这俩符号的意思,最近翻看代码又看到了,仍然觉得熟悉又陌生,主要是自己平时写代码对这俩符号用的比较少.于是特地做个实验,加深下理解.可记的东西不多,这篇随笔算是随手一写吧. 上实验代码: 来源: ...