CSDN 编程竞赛三十五期题解

竞赛总览

CSDN 编程竞赛三十五期:比赛详情 (csdn.net)

竞赛题解

题目1、交换后的or

给定两组长度为n的二进制串,请问有多少种方法在第一个串中交换两个不同位置上的数字,使得这两个二进制串“位或”的结果发生改变?

这道题在第七期出现过一次,属于简单难度的题目。

思路:题目要求通过“移位”使得位或结果发生改变。可以考虑位或的结果什么时候会发生改变,从而推导出解决题目所需的代码。

位或当有一位非零时结果为真,否则结果为假。

题目要求只移动第一个串(位于上面的串)。

当上下都为1时,拿走上面的1不会改变这一位的结果。因此,如果遇到这种情况,需要把拿走的1放到上下都是0的位置上,这样才能使得位或结果发生改变。

前 | 后
10 | 01
10 | 10

还有另一种情况,对于浮动的1(上面是1,下面是0),将其拿走,放到下面是1的底座上,这样也可以改变这一位的位或结果,从而改变整体位运算的结果。

前 | 后
10 | 01
01 | 01

分析出这两种情况之后,就可以解决这道题目了。

题目2、争风吃醋的豚鼠

N个节点两两建边。不存在三个节点相互之间全部相连(连接成环)的情况。最多能建立多少条边?

#include 

int main () {
    int resu1t = 0;
    int n = 0;
    scanf ("%d", &n);
    while (n > 0) {
        resu1t += n - 1;
        n = n - 2;
    }
    return 0;
}

第十五期竞赛原题。

题目3、最长递增的区间长度

给一个无序数组,求最长递增的区间长度。例如:[5,2,3,8,1,9],最长区间[2,3,8]长度为3。

#include 

int main () {
    int result = 1;
    int n;
    scanf ("%d", &n);
    int data [n];
    for (int i = 0; i < n; i++) scanf ("%d", &data [i]);
    for (int i = 1, t = 1; i < n; i++) {
        t = data [i] >= data [i - 1] ? (t + 1) : 1;
        result = result >= t ? result : t;
    }
    return 0;
}

这个题也挺简单的,有多种解决方法。可以动态规划,也可以直接处理。

扫描整个区间,如果当前项大于或等于前一项,即可视为当前仍是递增的,此时递增长度+1;否则,递增长度归零(只有一项时,它本身可以视为递增的,因为归零实际上是将递增长度设置成1,而不是真的清零)。

如果递增长度比历史递增长度还要大,则更新结果。

扫描完毕之后,输出历史最大递增长度即可。

题目4、因数-数字游戏

小Q的柠檬汁做完了。她掏出了自己的数字卡牌,想要和别人做数字游戏。可是她又不想要输掉游戏。她制定好了规则,轮流出牌,每个人只能给出前1个人所出的牌的某个因子牌。但是这个因子不能是1或者该数本身。现在给出整数n。两个人开始做游戏,轮流给出上一张牌的某个因子牌,谁无法再给出因子牌则该人胜利,如果该整数无因子牌直接视为先手胜利,请判断先手在最优策略状态下能否必胜。

第十四期竞赛原题。

你可能感兴趣的:(CSDN,竞赛题解,算法,c++)