题解 P4759 【[CERC2014]Sums】

· · 题解

P4759 最良心

这是题目

配合博客使用效果更佳

大致题意

大致题意就是给定一个正整数n,求一个公差为1和为n的等差数列。

分析

这一道题我们可以用枚举来做。那么重点来了--枚举的量为什么呢?

我们在讨论这个问题前先要了解一个等差数列求和公式:数列和=(首项+末项)×项数/2

那么有了这个公式,数列和已知,那么未知的项数和首项我们要枚举的量为-----项数,因为首项和末项要用到公差(已知为1)和项数来得出

推公式

在原公式中有两个未知量,但我们知道公差为1,所以可以把其中一个未知量--末项表示为首相+项数-1,公式可以表示为和=(首项+首项+项数-1)×项数/2

两边同时×2:和×2=(首项+首项+项数-1)×项数

两边同时/项数:和×2/项数=首项+首项+项数-1

两边同时+1:和×2/项数+1=首项+首项+项数

两边同时-项数:和×2/项数-项数+1=首项×2

枚举项数我们就可以得到首项,然后你会发现:

这不就是我们要的么

代码

评测记录

这是你们最喜欢的带注释的 Code

#include<bits/stdc++.h>
using namespace std;
int n,t;//声明 
int main() {
    scanf("%d",&t);
    while(t--) {//t组数据 
        scanf("%d",&n);
        n*=2;//先将和*2便于处理和判断 
        bool iss=0;//用来判断是否有解 
        for (int i=2; i*i<=n; i++) {//枚举项数 
            if(n%i!=0) continue;//只需要用和*2去除以项数即可判断合法 
            int x=(n/i-i+1)/2,y=x+i-1;//左右端点 
            if ((n/i-i+1)%2==0) {//判断首项是否为整数,也就是首项*2是否为偶数 
                printf("%d = %d",n/2,x);//先输出总和and首项 
                iss=true;//记录iss为真也就是有解 
                for(int l=x+1; l<=y; l++) cout<<" + "<<l;//从tmp+1输出数列因为左端点在15行输出过了 
                break;//跳出循环节省时间 
            }
        }
        if(!iss)/*如果iss=false也就是无解*/ printf("IMPOSSIBLE");
        printf("\n"); //换行
    }
    return 0;
}

最后是为了方便同学们复制Code

#include<bits/stdc++.h>
using namespace std;
int n,t;
int main() {
    scanf("%d",&t);
    while(t--) {
        scanf("%d",&n);
        n*=2;
        bool iss=0;
        for (int i=2; i*i<=n; i++) {
            if(n%i!=0) continue;
            int x=(n/i-i+1)/2,y=x+i-1;
            if ((n/i-i+1)%2==0) {
                printf("%d = %d",n/2,x);
                iss=true;
                for(int l=x+1; l<=y; l++) cout<<" + "<<l;
                break;
            }
        }
        if(!iss) printf("FANGCHAOXI");
        printf("\n");
    }
    return 0;
}

完(dian)结(ge)撒(zan)花(ba)~~

欢迎来我的博客看看