首页 > 其他分享 >2022暑假每日一题笔记(六)

2022暑假每日一题笔记(六)

时间:2022-08-26 19:25:23浏览次数:98  
标签:结点 2022 int 样例 cin 笔记 st -- 暑假

T1--4519. 正方形数组的数目

给定一个非负整数数组 A,如果该数组每对相邻元素之和是一个完全平方数,则称这一数组为正方形数组。
返回 A 的正方形排列的数目。
两个排列 A1 和 A2 不同的充要条件是存在某个索引 i,使得 A1[i]≠A2[i]。

输入格式
第一行包含一个整数 n,表示数组 A 的长度。
第二行包含 n 个整数 A[i]。

输出格式
一个整数,表示 A 的正方形排列的数目。

数据范围
1≤n≤12,
0≤A[i]≤10^9。

输入样例:
3
1 17 8
输出样例:
2
样例解释
[1,8,17] 和 [17,8,1] 都是有效的排列。

有重复元素的无重复全排列。
开始想尝试 next_permutation,不好处理,还是直接DFS。

参考题解: https://www.acwing.com/solution/content/126342/。

#include <bits/stdc++.h>
using namespace std;
const int N =15;
int n,q[N],ans;
bool st[N];

bool check(int x){ // 判断完全平方数
    int t = sqrt(x);
    return t*t == x;
}

void dfs(int u,int last){ // u表示搜索层数,last表示上次枚举的数
    if (u >= n){ // 把 n 个数枚举完就能得到一个答案序列
        ans ++; // 和蓝桥杯模板题的排列枚举略有不同,那题u = 1时开始枚举第一个数
        // 本题u = 1时第一个数已经确定
        return;
    }
    
    for (int i = 0;i < n;i ++){
        if (st[i]) continue; // 判重,用过的数字不能再用
        //举例[3 3 5 6], 如果当前6是元素,那么第二层会是3 3 5其中一个
        //然后我们如果第二层连续两次使用这个相同的3,就会使得搜到的结果是一样的
        //[6 3(第一个3) 5 3(第二个三)]  === [6 3(第二个3) 5 3(第一个三)]
        //所以需要跳过,只需要搜其中一个就行
        // 然后为什么要判断这个呢 (!st[i - 1]) 因为前面一个数肯定是回溯之后,
        //恢复现场了,st肯定是false,
        //如果是被标记的,说明是相同元素而已,dfs的不同层数
        if (i && !st[i-1] && q[i] == q[i-1]) continue; // 排除重复排列
        if (check(last + q[i])){
            st[i] = true;
            dfs(u+1,q[i]);
            st[i] = false;
        }
    }
}

int main(){
    cin >> n;
    for (int i = 0;i < n;i ++) cin >> q[i];
    
    sort(q,q + n);
    for (int i = 0;i < n;i ++){
        // 限定枚举的第一个数字不能重复
        if (i && q[i] == q[i-1]) continue; 
        st[i] = true; // 判重
        dfs(1,q[i]);
        st[i] = false;
    }
    cout << ans << '\n';
    return 0;
}

T2--3432. 二叉树

     1
    / \
   2   3
  / \ / \
 4  5 6  7
/\ /\ /\ /\
...     ... 
如上图所示,由正整数 1,2,3,… 组成了一棵无限大的(满)二叉树。
从任意一个结点到根结点(编号是 1 的结点)都有一条唯一的路径,比如从 5 到根结点的路径是 (5,2,1),从 4 到根结点的路径是 (4,2,1),从根结点 1 到根结点的路径上只包含一个结点 1,因此路径就是 (1)。

对于两个结点 x 和 y,假设他们到根结点的路径分别是 (x1,x2,…,1) 和 (y1,y2,…,1),那么必然存在两个正整数 i 和 j,使得从 xi 和 yj 开始,有 xi=yj,xi+1=yj+1,xi+2=yj+2,…
现在的问题就是,给定 x 和 y,要求他们的公共父节点,即 xi(也就是 yj)。

输入格式
1≤x,y≤2^31−1
输入样例:
10 4
输出样例:
2

参考题解: https://www.acwing.com/solution/content/126489/。

#include <bits/stdc++.h>
using namespace std;
          
int main(){
    int a,b;
    cin >> a >> b;
    
    while (a != b){
        if (a > b) a /= 2;
        if (b > a) b /= 2;
    }
    cout << a << '\n';
    return 0;
}

T3--3559. 围圈报数

N 个人围成一圈顺序编号,从 1 号开始按 1、2、3 顺序报数,报 3 者退出圈外,其余的人再从 1、2、3 开始报数,报 3 的人再退出圈外,依次类推。
请按退出顺序输出每个退出人的原序号。
要求使用环行链表编程。

输入格式
第一行包含整数 T,表示共有 T 组测试数据。
每组数据一行,一个整数 N。

输出格式
每组数据输出一行,一个结果,包含每个退出人的原序号,用空格隔开。

数据范围
1≤T≤5,
1≤N≤50
输入样例:
1
4
输出样例:
3 2 4 1

数组模拟循环链表,画个图方便理解。
优质题解: https://www.acwing.com/solution/content/126684/。

#include <bits/stdc++.h>
using namespace std;
const int N = 55;
int m,n,e[N],ne[N],idx;

int main(){
    cin >> m;
    while (m --){
        cin >> n;
        
        idx = 0; // 记得重置!
        for (int i = 1;i < n;i ++){
            e[++idx] = i,ne[idx] = i + 1;
        }
        e[n] = n,ne[n] = 1;
        
        int st = 1;
        while (ne[st] != st){
            int t = ne[st];
            cout << e[ne[t]] << ' ';
            ne[t] = ne[ne[t]];
            st = ne[t];
        }
        cout << st << '\n';
    }
    
    return 0;
}

T4--3588. 排列与二进制

在组合数学中,我们学过排列数。
从 n 个不同元素中取出 m(m<=n)个元素的所有排列的个数,叫做从 n 中取 m 的排列数,记为 p(n,m)。
具体计算方法为 p(n,m)=n(n−1)(n−2)……(n−m+1)=n!/(n−m)!(规定 0!=1)。
当 n 和 m 不是很小时,这个排列数是比较大的数值,比如 p(10,5)=30240。
如果用二进制表示为 p(10,5)=30240=(111011000100000)b,也就是说,最后面有 5 个零。
我们的问题就是,给定一个排列数,算出其二进制表示的后面有多少个连续的零。

输入格式
输入包含多组测试数据。
每组数据占一行,包含两个整数 n,m。
最后一行为 0 0,表示输入结束,无需处理。

输出格式
每组数据输出一行,一个结果,表示排列数 p(n,m) 的二进制表示后面有多少个连续的零。

数据范围
1≤m≤n≤10000,
输入最多包含 100 组数据。

输入样例:
10 5
6 1
0 0
输出样例:
5
1

组合数问题,不会,参考y总。
二进制末尾连续的0的数量等于这个数字包含因子2的数量。
根据公式,n!中有质因子p的个数为(\(\frac n p + \frac n {p^2} + \frac n {p^3} + ...\)),时间复杂度为:O(logn)

举例:当n=12,p=2时:
\(\frac n p\) 表示1~12中有6个数是2的倍数,即2,4,6,8,10,12
\(\frac n {p^2}\) 表示1~12中有3个数是4的倍数,即4,8,12,它们能在提供2的基础上多提供一个2
\(\frac n {p^3}\) 表示1~12中有1个数是8的倍数,即8,它能在提供两个2的基础上又多提供一个2
所以答案为6+3+1=10

y氏证明:

#include <bits/stdc++.h>
using namespace std;
int n,m;

int f(int x,int p){ // f(x,p)求x!中质因子p的指数,即x!中含有多少个质因子p
    int res = 0; // f(x,p) = x/p + x/p^2 + ... + x/p^i
    while (x) x /= p,res += x;
    return res;
}

int main(){
    while (cin >> n >> m && m){
        cout << f(n,2) - f(n-m,2) << '\n';
    }
    
    return 0;
}

T5--3555. 二叉树

给定一个 n 个结点(编号 1∼n)构成的二叉树,其根结点为 1 号点。
进行 m 次询问,每次询问两个结点之间的最短路径长度。
树中所有边长均为 1。

输入格式
第一行包含一个整数 T,表示共有 T 组测试数据。
每组数据第一行包含两个整数 n,m。
接下来 n 行,每行包含两个整数,其中第 i 行的整数表示结点 i 的子结点编号。如果没有子结点则输出 −1。
接下来 m 行,每行包含两个整数,表示要询问的两个结点的编号。

输出格式
每组测试数据输出 m 行,代表查询的两个结点之间的最短路径长度。

数据范围
1≤T≤10,
1≤n,m≤1000
输入样例:
1
8 4
2 3
4 5
6 -1
-1 -1
-1 7
-1 -1
8 -1
-1 -1
1 6
4 6
4 5
8 1
输出样例:
2
4
2
4

树的LCA问题,不会。

对于树上两点的最短路问题,可以转化为图上两点的最短路问题,树上两点的路径是唯一的,可以直接DFS或BFS。

或者可以结合DFS和LCA算法,然后用倍增法或Tarjan算法求解LCA,还可以用朴素版的LCA算法。

Tarjan算法求解LCA是离线算法,倍增法求解LCA是在线算法。

#include <bits/stdc++.h>
using namespace std;
const int N = 1005;
int l[N],r[N],p[N],dist[N],m,n;

void dfs(int u,int d){ // 计算每个结点到根结点的距离dist
    dist[u] = d;
    if (l[u] != -1) dfs(l[u],d+1);
    if (r[u] != -1) dfs(r[u],d+1);
}

int get_lca(int x,int y){ // 求解结点x与y的LCA编号
    // 朴素版LCA算法求解流程
    // 1.将深度更大的结点向上走到和另一结点同一层的深度
    // 2.然后两结点同时向上走,直到两结点走到同一点,即为LCA
    if (dist[x] < dist[y]) return get_lca(y,x); // dist值相等表示在同一层
    while (dist[x] != dist[y]) x = p[x];
    while (x != y) x = p[x],y = p[y];
    return x;
}

int main(){
    int t;
    cin >> t;
    while (t --){
        cin >> n >> m;
        
        int x,y;
        for (int i = 1;i <= n;i ++){
            cin >> x >> y;
            l[i] = x,r[i] = y;
            if (x != -1) p[x] = i;
            if (y != -1) p[y] = i;
        }
        
        dfs(1,0);
        
        int a,b;
        while (m --){ // 处理询问
            cin >> a >> b;
            int c = get_lca(a,b);
            cout << (dist[a] + dist[b] - 2*dist[c]) << '\n';
        }
    }
    return 0;
}

T6--4520. 质数

给定一个正整数 X,请你在 X 后面添加若干位数字(至少添加一位数字;添加的数不能有前导0),使得结果为质数,在这个前提下所得的结果应尽量小。

输入格式
第一行包含一个整数 T,表示共有 T 组测试数据。
每组数据占一行,包含一个整数 X。

输出格式
每组数据输出一行结果,一个整数,表示所得的满足条件的最小质数。

数据范围
1≤T≤100,
1≤X≤100。

输入样例:
1
1
输出样例:
11

不会,参考y总。
题目数据范围有限,直接枚举要添加的数即可。

#include <bits/stdc++.h>
using namespace std;

bool check(int a){
    if (a < 2) return false;
    for (int i = 2;i*i <= a;i ++){
        if (a % i == 0) return false;
    }
    return true;
}

int main(){
    
    int t,x;
    cin >> t;
    while (t --){
        cin >> x;
        
        for (int i = 1;;i ++){
            string str = to_string(x) + to_string(i);
            int a = stoi(str);

            if (check(a)){
                cout << a << '\n';break;
            }
        }
    }
    return 0;
}

标签:结点,2022,int,样例,cin,笔记,st,--,暑假
From: https://www.cnblogs.com/grant-drew/p/16503618.html

相关文章

  • 2022/8/26 总结
    A.括号序列一看,我趣,字符串,直接抱灵吧,让我死得体面一点……再一看数据范围,我趣,\(\mathtt{O(n)}\),这怎么写得出来啊?Solution虽然是\(\mathtt{O(7n)}\),但卡卡常......
  • 肖sir__jenkins搭建20220826
    Jenkins操作手册1、持续集成(CI)Continuousintegration 持续集成 团队开发成员每天都有集成他们的工作,通过每个成员每天至少集成一次,也就意味着一天有可 能多......
  • 2022 NOI 游记
    Day-2起的很早,大概是\(8:00\)左右就到了酒店前台那里,退了房然后去学校了。\(9:00\)左右就到了昆山迪邦华耀学校。(做的出租车去的,下车的时候司机锐评:\(NOI\)不如游戏......
  • 2022-08-26 第二组刘禹彤 学习笔记
    打卡41天###学习内容JS库别人写好的JS文件,我们拿来直接用--------开发中会引入很多.js文件JQery.js:濒临淘汰,经典,10%以下市场React.js:30%市场Angular.js:10%以下市......
  • 2022-8-25 第四组 曹雨 Java script HTML元素操作,BOM
    对HTML元素的操作获取某个元素的属性的值:方法1:元素.属性名特别注意:元素.属性名的方式只适用于元素原生的属性,自定义的属性是拿不到的例子:console.log(div.id)方法2:......
  • NOI2022 游记
    本来叫游寄的,但我好像寄的程度好像无足轻重。隔离7天到达世界最热城,昆山,,,,,,不对,好像整个长江流域都这么热,,,,,,大概隔一天打一场模拟赛,几天前经常切自己赛后不会的题,状态不如......
  • NOI2022 进队记
    Day-2十一点钟左右从宾馆出发去学校,我一看宾馆距离学校只有十公里那还不如直接走过来咯。进学校已经是午饭点了,去宿舍的时候看到一车人已经在吃饭了。鉴于我从来没有参......
  • NOI2022游记
    我有一种感觉,就是我真的是来旅游的.jpg因此这个游记可能真的会成为游记()正经一点的带考试版本还是等考完之后发布。8.13前突然得知要提前去昆山。太好了!8.13坐高铁,由......
  • Spring学习笔记(1)实现简单的Bean容器
    github地址代码目录结构small-spring-step-01└──src├──main│└──java│└──cn.bugstack.springframework│......
  • MATLAB R2022a中文版下载及安装教程(图文详解免费版)
    一、下载下载地址:点击下载二、安装激活1、如果安装有旧版本,请先卸载;2、使用WinRAR解压镜像文件,或者win10直接加载,点击“setup.exe”开始安装;3、点击右上角高级选项,选......