A题:

https://www.nowcoder.com/acm/contest/185/A

链接:https://www.nowcoder.com/acm/contest/185/A
来源:牛客网

题目描述

给出一个二元组(A,B)
求出无序二元组(a,b) 使得(a|A,b|B)的组数
无序意思就是(a,b)和(b,a) 算一组.

输入描述:

  1. 第一行数据组数 T1T10000
    接下来T行,每行两个正整数 A,B1A,B10000

输出描述:

  1. T行,每行一个结果

输入例子:
  1. 1
  2. 4 6
输出例子:
  1. 11

-->

示例1

输入

复制

  1. 1
  2. 4 6

输出

复制

  1. 11

说明

  1. 样例解释:
    二元组如下:
    (1,1)(1,2)(1,3)(1,6)
    (2,1)(2,2)(2,3)(2,6)
    (4,1)(4,2)(4,3)(4,6)
    12组.
    无序二元组如下:
  2.  
  3. (1,1)(1,2)(1,3)(1,6)
    (2,2)(2,3)(2,6)
    (4,1)(4,2)(4,3)(4,6)
    11
  4.  
  5. 分析:
    题意很明确了,T组数据,给定两个数,让我们求这两个数的的约数可以组成多少个无序的二元组.
    我们可以这么做: 找出A, B的所有因子数, 然后相乘,再减去重复算的就是答案了.
  6.  
  7. 即: 答案 = |A| * |B| - |公共因子数| * |公共因子数 + 1| / 2; (从公共因子中选出2个,作为一个二元组, C(2,n) )
  8.  
  9. 然后我们观察数据,发现有T1e4, 然后A,B也是1e4的,如果A,B直接暴力找的话,那么每次查找约数都是O(sqrt(n))的,
    同时要判除相同的因子个数,如果常数大了,是很容易T的.(反正我的暴力解法是T了的)
  10.  
  11. 有一个结论: 两个数的公约数的个数为这个两个数的最大公约数的约数个数 ---> a,b两个数的公约数个数 = gcd(a,b)的约数个数.
    所以,我们可以预处理出1-10000的所有约数, 然后每次就可以O(1)的计算答案了.然后没了.
  12.  
  13. 代码:
  1. #include <cstdio>
  2. #include <cmath>
  3. #include <set>
  4.  
  5. using namespace std;
  6.  
  7. int pre[];
  8.  
  9. int gcd(int a, int b) { return !b ? a : gcd(b, a%b); }
  10.  
  11. int main() {
  12. int t, i, j, tmp, a, b;
  13. int res;
  14. set<int> se;
  15. for (i=; i<=; ++i) {
  16. tmp = sqrt(i);
  17. se.clear();
  18. for (j=; j<=tmp; ++j) {
  19. if (i%j==) {
  20. se.insert(j);
  21. se.insert(i / j);
  22. }
  23. }
  24. pre[i] = se.size();
  25. }
  26. scanf("%d", &t);
  27. while (t--) {
  28. scanf("%d%d", &a, &b);
  29. res = pre[a] * pre[b];
  30. res -= pre[gcd(a, b)] * (pre[gcd(a, b)]-)/;
  31. printf("%d\n", res);
  32. }
  33.  
  34. return ;
  35. }

-----------------------------------------------------------------------------------------------------------------------------------------这是一条分割线------------------------------------------------------------------------------------------------------------------

  1. B题:
    https://www.nowcoder.com/acm/contest/185/B
    链接:https://www.nowcoder.com/acm/contest/185/B
    来源:牛客网

题目描述

给出一个 n * n 的邻接矩阵A.
A是一个01矩阵 .
A[i][j]=1表示i号点和j号点之间有长度为1的边直接相连.
求出从 1 号点 到 n 号点长度为k的路径的数目.

输入描述:

  1. 1行两个数n,k (20 n 30,1 k 10)
    2行至第n+1行,为一个邻接矩阵

输出描述:

  1. 题目中所求的数目
示例1

输入

复制

  1. 4 2
  2. 0 1 1 0
  3. 1 0 0 1
  4. 1 0 0 1
  5. 0 1 1 0

输出

复制

  1. 2
  1. B题, 原理我还不是很懂,所以不讲.
    所以不如看别人的题解 https://www.nowcoder.com/discuss/104612?type=101&order=1&pos=2&page=1
  1. #include <cstdio>
  2. #include <cstring>
  3.  
  4. using namespace std;
  5.  
  6. typedef long long ll;
  7.  
  8. class Matrix {
  9. public:
  10. int r, c;
  11. ll mat[][];
  12.  
  13. ll *operator [] (int x) { return mat[x]; }
  14.  
  15. Matrix operator * (const Matrix &a) const {
  16. Matrix res;
  17. res.r = r; res.c = a.c;
  18. int i, j, k;
  19. for (i=; i<=res.r; ++i) {
  20. for (j=; j<=res.c; ++j) {
  21. res[i][j] = ;
  22. for (k=; k<=c; ++k)
  23. res[i][j] += mat[i][k] * a.mat[k][j];
  24. }
  25. }
  26. return res;
  27. }
  28.  
  29. }m;
  30.  
  31. Matrix pwr(const Matrix &a, int k) {
  32. Matrix base = a, r;
  33. int i, j;
  34. r.r = a.r; r.c = a.c;
  35. for (i=; i<=r.r; ++i)
  36. for (j=; j<=r.c; ++j)
  37. r[i][j] = i==j;
  38. while (k) {
  39. if (k & ) r = r * base;
  40. base = base * base;
  41. k >>= ;
  42. }
  43. return r;
  44. }
  45.  
  46. int main()
  47. {
  48. int n, k, i, j;
  49. scanf("%d%d", &n, &k);
  50. for (i=; i<=n; ++i)
  51. for (j=; j<=n; ++j)
  52. scanf("%d", &m[i][j]);
  53. m.r = n; m.c = n;
  54. m = pwr(m, k);
  55. printf("%lld\n", m[][n]);
  56. return ;
  57. }

C题:

https://www.nowcoder.com/acm/contest/185/C

链接:https://www.nowcoder.com/acm/contest/185/C
来源:牛客网

题目描述

给出一个数列 A,求出一个数列B.
其中Bi   表示 数列A中 Ai 右边第一个比 Ai 大的数的下标(从1开始计数),没有找到这一个下标  Bi 就为0
输出数列B

输入描述:

第一行1个数字 n (n ≤ 10000)
第二行n个数字第 i 个数字为 Ai (0 ≤ A≤ 1000000000)

输出描述:

  1. 一共一行,第 i 个数和第 i+1 个数中间用空格隔开.

输入例子:
  1. 6
  2. 3 2 6 1 1 2
输出例子:
  1. 3 3 0 6 6 0

-->

示例1

输入

  1. 6
  2. 3 2 6 1 1 2

输出

  1. 3 3 0 6 6 0
  2.  
  3. 分析: 题意很简单,在数列中从左往右,找到第一个比当前数大的数的下标,如果没有,则为0.
    我们发现数据是1e4的...暴力貌似也就5e7....也许可以吧= =.我没暴力.
    暴力是正着扫的,复杂度是O(n^2) 我们不妨倒着考虑.
    1. 从最后一个数开始,往前找,如果找到一个比当前数A小的B, 那么B的答案应该是A的下标.
    如果找到一个比当前数A大的C, 那么C的答案应该由当前数A往右的数来决定,如果有比C大的那么C的答案不为0,否则为0;
    2. 基于这个想法,我们发现可以用一个队列来模拟这个过程:
    1). 从最后一个数开始,往前找,如果找到一个比当前数A(队首元素)小的B, 那么B的答案应该是A的下标. 同时B插到队首,
    如果找到一个比队首元素大的数C, 那么队首元素出队,直到找到一个比C大的数,或者队空.
    如果找到比C大的数, 那么C的答案更新为下标, 同时C插到队首,
    如果队空了, 那么C的答案为0, 同时C插到队首,
    2). 重复这个过程,直到遍历完整个数组,答案就更新完毕了.
    重点是想想,为什么要把更新元素插入到队首, 想想.
    这个也就是单调队列(队列里的元素是单调的. 优先队列里的元素也是单调的,不过有所不同.我暂时也讲不清,大概单调队列我也只会这种水题,,,)
  1. #include <cstdio>
  2. #include <queue>
  3.  
  4. using namespace std;
  5.  
  6. int date[];
  7. int ans[];
  8. struct nobe {
  9. int val;
  10. int id;
  11. nobe () { }
  12. nobe (int vv, int ii) : val(vv), id(ii) { }
  13. };
  14.  
  15. deque<nobe> dq;
  16.  
  17. int main()
  18. {
  19. int n, i;
  20. scanf("%d", &n);
  21. for (i=; i<=n; ++i) scanf("%d", date+i);
  22. for (i=n; i; --i) {
  23. if (dq.empty()) dq.push_front(nobe(date[i], i));
  24. else if (dq.front().val > date[i]){
  25. ans[i] = dq.front().id;
  26. dq.push_front(nobe(date[i], i));
  27. } else {
  28. while (!dq.empty() && dq.front().val <= date[i])
  29. dq.pop_front();
  30. i++;
  31. }
  32. }
  33. printf("%d", ans[]);
  34. for (i=; i<=n; ++i) printf(" %d", ans[i]);
  35. printf("\n");
  36. return ;
  37. }

D题:

链接:https://www.nowcoder.com/acm/contest/185/D

题目描述

Johnson和Nancy要在星光下吃晚餐。这是一件很浪漫的事情。

为了增加星光晚餐那浪漫的氛围,他拿出了一个神奇的魔法棒,并且可以按照一定的规则,改变天上星星的亮暗。

Johnson想考考Nancy,在他挥动魔法棒后,会有多少颗星星依旧闪耀在天空。他知道,Nancy一定会一口说出答案。

Nancy当然知道怎么做啦,但她想考考你!

Johnson先将天上n个星星排成一排,起初它们都是暗的。

他告诉他的妹子,他将挥动n次魔法棒,第i次挥动会将编号为i的正整数倍的星星的亮暗反转,即亮的星星转暗,暗的星星转亮。

Johnson想问Nancy,最终会有多少个星星依旧闪亮在天空。

输入描述:

  1. 一个整数n,含义请见题目描述。

输出描述:

  1. 一个整数ans,即n次操作后会有多少个星星依旧闪亮。

输入

  1. 3

输出

  1. 1

输入

  1. 7

输出

  1. 2

备注:

  1. 对于60%的数据:n2×10

6

  1. 对于100%的数据:n10

18

  1. 分析: 题目给你n个标号为1...n的初始为暗星星,然后你要开关n次, i次关闭标号为i的倍数的星星,问最后有多少个亮着的星星.
    范围: 1e18, 简单, 肯定暴力. 才怪. 所以应该是有公式或者规律可以O(1)算的.
    我们发现,对于一个星星,如果开关了偶数次,那么状态不变,最后还是暗的. 如果开关了奇数次,那么最后就亮的.
    所以我们的问题转化为: 被开关了奇数次的星星个数.
    i次关的是i的倍数的星星, 我们可以反过来考虑, 对于一个标号为k的星星来说,它会在x次被关闭,当且仅当x|k.(x整除k), xk的因子.
    所以,我们的问题又转化为了: 1...n以内 因子个数是奇数的数的个数了.
    我们发现, 知道,只有平方数的因子个数是奇数个,其他的都是偶数个.(想想.)
    所以,问题就是: 1...n以内,有多少个平方数.
    答案是sqrt(n)向下取整. (想想.)
  1. #include <cstdio>
  2. #include <cmath>
  3.  
  4. int main()
  5. {
  6. long long n, res;
  7. scanf("%lld", &n);
  8. res = sqrt(n);
  9. printf("%lld\n", res);
  10. return ;
  11. }

E题:

链接:https://www.nowcoder.com/acm/contest/185/E

题目描述

给定括号长度N,给出一串括号(只包含小括号),计算出最少的交换(两两交换)次数,使整个括号序列匹配。
我们认为一个括号匹配,即对任意一个')',在其左侧都有一个'('与它匹配,且他们形成一一映射关系。

输入描述:

  1. 第一行:整数N,表示括号序列长度
    第二行:一个字符串,表示括号

输出描述:

  1. 一个整数,表示最少的交换次数

输入

  1. 6
  2. (()))(

输出

  1. 1

输入

  1. 6
  2. )))(((

输出

  1. 2
    分析: 题意就是给一个括号串,问最小交换多少次,可以让括号串括号都可以匹配.
    1. 很自然的想法, 如果已经匹配了的括号,那么我们肯定不需要交换它们了.
    2. 如果我们删除本来就匹配了的括号,那么剩下的括号一定是))))))))))))))(((((((((((这种形式了.
    3. 对于这种剩下的括号,如果是有偶数对,那么我们贪心的交换,一次都可以匹配2对, 而且这便是最优的了.
    4. 如果剩下奇数对,我们最后一对也需要交换一次.
    所以,我们交换次数 = (总括号对数 - 原先就匹配了的对数 + 1 ) / 2 即: (未匹配括号对数+1) / 2
  2.  
  3. 然后,我们怎么求解已经匹配了的括号对数呢? 很简单,我们直接用一个栈来模拟. 遇到左括号入栈,遇到右括号,如果栈有元素出栈,匹配数++,如果栈为空,继续扫下一个字符.
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. char str[];
  4. int main()
  5. {
  6. int n, i, cnt = ;
  7. scanf("%d%s", &n, str);
  8. stack<char> st;
  9. for (i=; i<n; ++i)
  10. if (str[i] == '(') st.push(str[i]);
  11. else if (!st.empty()) st.pop(),cnt++;
  12. printf("%d\n", (n/ - cnt + ) / );
  13. return ;
  14. }

F题:

链接:https://www.nowcoder.com/acm/contest/185/F

题目描述

输入一个整数X,求一个整数N,使得N!恰好大于XX

输入描述:

  1. 第一行:一个整数X

输出描述:

  1. 第一行:一个整数N

输入

  1. 7

输出

  1. 10

备注:

  1. 每个测试点所对应的X满足:
  2.  
  3. i个测试点输入的值为第i-1个测试点输入的值乘以10再加上7
  4.  
  5. 特别的,第一个测试点所输入的值为7
  6.  
  7. 提示:数据共有10组。
  1. 分析: 要找到满足N! > X^X , 我们发现X最后会很大, 计算用高精度也肯定爆,所以我们考虑用数学方法.
    我们可以两边取一个对数 那么就有 lgN! > XlgX 然后根据题意,X最多1e9 那么,我们就可以用二分,来枚举N了.
    那么lgN!应该怎么算呢? N!有一个近似的公式: 斯特林公式:

  然后,我们就有 lg(sqrt(2 * PI * n)) + n * lg(n / e) > X lgX ,然后就可以愉快的二分了, 当然要注意精度问题.(...我不懂精度)

  1. #include <iostream>
  2. #include <cmath>
  3.  
  4. using namespace std;
  5.  
  6. const double PI = acos(-1.0);
  7. const double e = exp(1.0);
  8. const double eps = 1e-;
  9. int main()
  10. {
  11. // freopen("E:\\input.txt", "r", stdin);
  12. long double x;
  13.  
  14. while (cin >> x) {
  15. x = x * log(x);
  16. long double left = 0.0, right = 9999999999.0;
  17. while (right - left > eps) {
  18. long double n = (left + right) / 2.0;
  19. long double jc = log( * PI * n) / 2.0 + n * log(n / e);
  20. if (jc > x) {
  21. right = n;
  22. } else {
  23. left = n;
  24. }
  25. }
  26. cout << (long long)left + << endl;
  27. }
  28.  
  29. return ;
  30. }
  31. /*
  32. 10
  33. 94
  34. 892
  35. 8640
  36. 84657
  37. 834966
  38. 8267019
  39. 82052137
  40. 815725636
  41. 8118965902
  42. */

牛客OI赛制测试赛2的更多相关文章

  1. 【牛客OI赛制测试赛3】 毒瘤xor

    牛客OI赛制测试赛3 毒瘤xor 传送门 题面,水表者自重 Solution 前缀和简单题(挖坑待补) 代码实现 #include<stdio.h> #define int long lo ...

  2. 牛客OI赛制测试赛2(0906)

    牛客OI赛制测试赛2(0906) A :无序组数 题目描述 给出一个二元组(A,B) 求出无序二元组(a,b) 使得(a|A,b|B)的组数 无序意思就是(a,b)和(b,a) 算一组. 输入描述: ...

  3. 8.30 牛客OI赛制测试赛1 F题 子序列

    题目描述 给出一个长度为n的序列,你需要计算出所有长度为k的子序列中,除最大最小数之外所有数的乘积相乘的结果 输入描述: 第一行一个整数T,表示数据组数.对于每组数据,第一行两个整数N,k,含义如题所 ...

  4. C数列下标 牛客OI赛制测试赛2

    链接:https://www.nowcoder.com/acm/contest/185/C来源:牛客网 给出一个数列 A,求出一个数列B. 其中Bi   表示 数列A中 Ai 右边第一个比 Ai 大的 ...

  5. 牛客OI赛制测试赛2 D 星光晚餐

    链接:https://www.nowcoder.com/acm/contest/185/D来源:牛客网 题目描述 Johnson和Nancy要在星光下吃晚餐.这是一件很浪漫的事情. 为了增加星光晚餐那 ...

  6. 牛客OI赛制测试赛2 C 数组下标

    链接:https://www.nowcoder.com/acm/contest/185/C来源:牛客网 题目描述 给出一个数列 A,求出一个数列B. 其中Bi   表示 数列A中 Ai 右边第一个比 ...

  7. 牛客OI赛制测试赛2 A 无序组数

    链接:https://www.nowcoder.com/acm/contest/185/A来源:牛客网 题目描述 给出一个二元组(A,B) 求出无序二元组(a,b) 使得(a|A,b|B)的组数 无序 ...

  8. Nowcoder | [题解-N189]牛客OI赛制测试赛3

    这场说实话确实水(逃*1),表示差一点就AK了(逃*2),然而被卡两个特判的我\(ssfd\)...\(qwq\) 表示这是第一次发整场比赛的题解...还请各位大佬原谅我太蒻写的垃圾啊\(qwq\). ...

  9. 牛客OI赛制测试赛-序列-模拟

    哇这道题好坑啊,可能是我太菜了 题意就是叫把一个连续序列分成K组,使得每个组的和都相等 我最开始的想法是由于要分成K组,那我们知道,每组一定有sum(a[i])/k这样我们只需要每次当num==sum ...

随机推荐

  1. time_wait 和 close_wait

    tcp 四次握手状态图: 使用以下命令统计 tcp 连接信息: netstat -n |awk '/^tcp/ {++S[$NF]} END {for (a in S) print a, S[a]}' ...

  2. Python3红楼梦人名出现次数统计分析

    一.程序说明 本程序流程是读取红楼梦txt文件----使用jieba进行分词----借助Counter读取各人名出现次数并排序----使用matplotlib将结果可视化 这里的统计除了将“熙凤”出现 ...

  3. MP3文件结构解析(超详细)

    转自:http://blog.csdn.net/u010650845/article/details/53520426 MP3文件结构解析(超详细) 1. MP3文件结构解析 1.1. 概述 1.1. ...

  4. GsonFormat根据返回值json快速构建Model

    Json是一个插件,我们只需要在Android studio中进行安装一下,即可使用. 根据平时的操作,根据浏览器中返回中的数据一行一行敲,其实这样非常麻烦. 有一个简单的方法,可以瞬间生成一个实体类 ...

  5. ssh免输入密码登录

    ssh免输入密码登录   ubuntu下生成ssh密钥参见.   https://confluence.atlassian.com/display/BITBUCKET/Use+the+SSH+prot ...

  6. linux文件管理 文件操作

    文件操作 pwd 命令 该命令的英文解释为print working direction(打印工作目录).输入pwd命令,Linux输出当前目录. cd 命令 用来改变所在目录 cd / 转到根目录 ...

  7. Win10系列:C#应用控件基础5

    ListBox控件 上一小节介绍的ComboBox控件在外观上仅显示当前选中的选项,通过单击此控件文本框才能看到其他选项,而ListBox控件能够以列表形式始终显示选项.在ListBox控件中可以添加 ...

  8. Unity3D中的射线与碰撞检测代码

    两种不同写法的射线检测 1.获取鼠标点击的物体 if (Input.GetMouseButtonDown(0)) { Ray ray = MainCamera.ScreenPointToRay(Inp ...

  9. U帮忙U盘装系统工具使用教程

    在用U盘装系统时首先我们需要了解一下U帮忙U盘启动盘的制作以及BIOS设置U盘启动和U盘装系统步骤后才能让操作更顺利的完成,下面就来说说U帮忙U盘装系统工具使用教程,希望对大家有所帮助! 如果您不了解 ...

  10. objectstate对象三种状态

    1.临时状态:new对象的过程,刚被创建出来,数据库中没有对应数据 2.持久状态:session.save(),数据库中有对应数据,session中也有对应数据 3游离状态:数据库中有对应数据,ses ...