题目描述
小Z家住在一条短胡同里,这条胡同的门牌号从 1 开始顺序编号。
若其余各家的门牌号之和减去小Z家门牌号的两倍,恰好等于n,求小Z家的门牌号及总共有多少家。(有多解的情况下输出总家庭数最少的方案,题目肯定有解)
输入
一个正整数T(10<=T<=1000),表示一共有T组询问
接下来T行,每行一个整数n(0 < n < 100000)
输出
输出一共T行,每行两个整数a b(用空格隔开,表示小Z家的门牌号及总共有多少家,有多解的情况下输出总家庭数最少的方案)
输入样例 复制
5 15 90 63 46 3
输出样例 复制
2 6 5 14 1 11 3 10 1 3
这道题看一下数据就知道肯定是要枚举人家数++,数学求小z家的门牌号。
搞了好久想到了前缀和解法:
for(int i=1;i<=ax/2+4;i++)
s[i]=s[i-1]+i;
就是有i家时房号总和,再小z家=(s[i]-n)/3,也有判断:if((s[i]-o)%3==0&&(s[i]-o)/3<=i&&s[i]-o>0) cout......
结果 答案错误 0 一打开10个Time Limit Exceeded 熬了几天没出来,看了下视频前一分钟炸了。
高斯求和!!!//划重点了!!!
高斯总房和
简单了,枚举总房间数,n=(房数*(房数+1))/2-小z-2*小z
去分母合并同类项移项得 小z=(i*i+i-2*n)/6 (枚举房总数为i)
条件就是(i*i+i-2*n)/6能整除,且>0
精髓高斯、判断、枚举......函数:
void jie(int n)
{
for(int i=1;;i++) 不写条件,一定有解
if((i*i+i-2*n)%6==0&&i*i+i-2*n>0&&(i*i+i-2*n)/6<=i)
{
cout<<(i*i+i-2*n)/6<<' '<<i<<endl;
return;
}
}
#include<bits/stdc++.h>
using namespace std;
void USA(int n)
{
int y=1,t=0;
while(1)
{
t=y*(y+1)-2*n;
if(t>0&&t%6==0)
{
cout<<t/6<<" "<<y<<endl;
return;
}
y++;
}
}
int main()
{
int t,n;
cin>>t;
for(int i=1;i<=t;i++)
{
cin>>n;
USA(n);
}
return 0;
}
该博客讨论了一道算法题目,涉及到寻找小Z家的门牌号,其中胡同中其他家庭门牌号之和减去小Z家门牌号的两倍等于给定的数n。博主通过尝试枚举法和前缀和方法来解决,最终发现利用高斯求和公式可以简化问题,得出小Z家门牌号的公式(i*i+i-2*n)/6,并给出了满足条件的最小家庭数解决方案。


1507

被折叠的 条评论
为什么被折叠?



