题解 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)~~
欢迎来我的博客看看