题目一:
小Q定义了一种数列称为翻转数列:
给定整数n和m, 满足n能被2m整除。对于一串连续递增整数数列1, 2, 3, 4..., 每隔m个符号翻转一次, 最初符号为'-';。
例如n = 8, m = 2, 数列就是: -1, -2, +3, +4, -5, -6, +7, +8.
而n = 4, m = 1, 数列就是: -1, +2, -3, + 4.
小Q现在希望你能帮他算算前n项和为多少。

思路:
这是一道规律题,找到规律再写程序就要简介很多。

从题目给出的两个例子:
n = 8, m = 2, 数列就是: -1, -2, +3, +4, -5, -6, +7, +8.
n = 4, m = 1, 数列就是: -1, +2, -3,

  • 可以看出数列被分为n/m2部分,其中每部分的和都相等,所以题目要求的前n项和一定为每部分求和之和,即部分数每部分的和;
  • 那么每部分的和是多少呢,通过题目给出的例子可知:
    当n = 8, m = 2时,部分和为4=2的平方
    当n = 4, m = 1时,部分和为1=1的平方
    以此类推,可以得到部分和为m的平方。

所以,这道题目的最终求解就是在求m*n/2的值。

程序如下:

#include<iostream>
using namespace std;
    typedef long long LL;
int main()
{
    LL n,m;
    cin>>n>>m;
    cout<<n*m/2<<endl;
}

题目二:
牛牛和羊羊正在玩一个纸牌游戏。这个游戏一共有n张纸牌, 第i张纸牌上写着数字ai。
牛牛和羊羊轮流抽牌, 牛牛先抽, 每次抽牌他们可以从纸牌堆中任意选择一张抽出, 直到纸牌被抽完。
他们的得分等于他们抽到的纸牌数字总和。
现在假设牛牛和羊羊都采用最优策略, 请你计算出游戏结束后牛牛得分减去羊羊得分等于多少。

思路:
首先解释一下什么是最优策略:所谓最优就是当轮到自己抽牌时直接选择最大的牌。

因为是两个人是相间抽牌,并且都会抽取最大的牌,所以只需在计算前排序即可,奇数位都是牛牛的,偶数位都是羊羊的。

程序如下:

#include<stdio.h>
#include<algorithm>
using namespace std;
const int MAXN=1e5+7;
int st[MAXN] = {0};
int cmp(int a, int b)
{
 return a>b;//降序排列
}
int main()
{
 int n = 0;
 long sum1 = 0;
 long sum2 = 0;
 long dif = 0;
 scanf("%d",&n);
 for (int i = 0; i<n; i++)
 {
  scanf("%d", &st[i]);
 }
 sort(st, st + n, cmp);
 for (int i = 0; i<n;)
 {
        if(i%2==0)
            dif+=st[i];
        else
            dif-=st[i];
  i++;
 }
 printf("%ld", dif);
 return 0;
}

题目三:
小Q的父母要出差N天,走之前给小Q留下了M块巧克力。小Q决定每天吃的巧克力数量不少于前一天吃的一半,但是他又不想在父母回来之前的某一天没有巧克力吃,请问他第一天最多能吃多少块巧克力。

思路:

使用二分查找法,可最大限度的加快查找速度,防止超时。(二分查找的找上届和找下界需要学习一下)

程序如下:

#include<iostream>
using namespace std;
int n,m;
//计算第一天吃s个巧克力一共需要多少个多少个巧克力
int sum(int s){
    int sum=0;
    for(int i=0;i<n;i++){
        sum+=s;
        s=(s+1)>>1;//向上取整
    }
    return sum;
}
//二分查找
int fun(){
    if(n==1) return m;
    int low=1;
    int high=m;//第一天的巧克力一定是大于等于1小于等于m的
    while(low<high){
        int mid=(low+high+1)>>1;//向上取整
        if(sum(mid)==m) return mid;//如果第一天吃mid个巧克力,刚刚好吃完所有巧克力,那么直接返回
        else if(sum(mid)<m){
            low=mid;
        }else{
            high=mid-1;
        }
    }
    return high;
}
int main()
{
    cin>>n>>m;
    int res=fun();
    cout<<res<<endl;
    return 0;
}