编程实现求出若干个整数之和为500的连续整数(如98,99,100,101,102),所有组合。
解决方案 »
- Winform弹出对话框问题
- c# 在WindowsFormsApplication中 添加图片
- csc 的 /unsafe 到底做了什么?
- wince C# ListView 中大图标怎么样加入图片或者ICON
- 用户控件中加入AJAX控件不能使用,怎么办
- C#应用程序与SQL数据库打包的问题
- 使用存储过程如何在前台绑定数据
- 100分求关于datagridview动态列中的Cells
- 古怪的ConfigurationManager,添加引用System.Configuration.dll依然无效
- 请教一下这种表结构,怎么生成treeview
- 如何创建封装控件的DLL,以供主窗体程序调用?
- 线程的问题
{
class Test
{
static void Main()
{
int sum=0;
for (int i=1;i<500;i++)
{
for (int j=i;j<500;j++)
{
sum=(j-i+1)*(i+j)/2;
if (sum==500)
{
Console.WriteLine("第一个数是{0} 最后一个数{1}",i,j);
}
}
}
Console.ReadLine(); }
}
}
bool vb;
for(int i=1; i<250; i++)
{
vb = true;
for(int j=i; j<250 && vb; j++)
{
if(((i+j)*(j-i+1)/2) == 500)
{
str = str + i+"abc ";
vb = false;
}
if(((i+j)*(j-i+1)/2) > 500)
{
vb = false;
}
}
}
如果是我肯定想不到
sum=(j-i+1)*(i+j)/2;
呵呵 忽然就想起来小时候说的 1+………………+100 = ???
这个用起来应该已经是比较快的了吧
没有想到更好的算法了!!~~
//shy
多了个-
{
Console.WriteLine("从{0}开始,{1}结束",x,n+x);
}==================
输出结果:
从98开始,102结束
从59开始,66结束
从8开始,32结束
从-7开始,32结束
从-58开始,66结束
从-97开始,102结束
for(int n=2;n<500;n++)
{
float fx=(1000.0f/(n+1)-n)/2; //看fx是不是整数
int x=(int)Math.Floor(fx); //取fx的整数 if((fx-x)<0.000001) //比较fx和x是否一样大小
{
Console.WriteLine("从{0}开始,{1}结束",x,n+x);
}
}
==================
输出结果:
从98开始,102结束
从59开始,66结束
从8开始,32结束
从-7开始,32结束
从-58开始,66结束
从-97开始,102结束
就是求 (2 * a + delta) * (delta + 1) = 1000 的所有整数解啊这个根本不需要写什么代码吧1000 = 10^3 = 2^3 * 5^3要分解成两数之积, 只可能以下几种情况
(2*a+delta) * (delta + 1)
-------------------------
(2^0 * 5^0) * (2^3 * 5^3)
(2^0 * 5^1) * (2^3 * 5^2)
(2^0 * 5^2) * (2^3 * 5^1)
(2^0 * 5^3) * (2^3 * 5^0)(2^1 * 5^0) * (2^2 * 5^3)
(2^1 * 5^1) * (2^2 * 5^2)
(2^1 * 5^2) * (2^2 * 5^1)
(2^1 * 5^3) * (2^2 * 5^0)(2^2 * 5^0) * (2^1 * 5^3)
(2^2 * 5^1) * (2^1 * 5^2)
(2^2 * 5^2) * (2^1 * 5^1)
(2^2 * 5^3) * (2^1 * 5^0)(2^3 * 5^0) * (2^0 * 5^3)
(2^3 * 5^1) * (2^0 * 5^2)
(2^3 * 5^2) * (2^0 * 5^1)
(2^3 * 5^3) * (2^0 * 5^0)剩下的就简单得很了,比方(2^3 * 5^2) * (2^0 * 5^1) = (2 * a + delta) * (delta + 1)
2^0 * 5^1 = delta + 1 ,所以 delta = 4
2^3 * 5^2 = 2 * a + delta , 所以 a = 98, 即 (98, 102)过滤其中的小数解,就可以了,这个要比上面完全搜索要快得多吧
{
int sum = 0;
for( int X = 1 ; X < 500 ; X ++ )
{
for( int step = 0 ; step < n ; step ++ )
{
sum += X + step;
}
if( sum == 500 )
{
Console.WriteLine( n.ToString() + " 个数: " );
for( int step = 0 ; step < n ; step ++ )
{
Console.WriteLine( Convert.ToString( X + step ) + ";" );
}
break;
}
sum = 0;
}
}/// 测试过 : 得到的结果是 :5 个数:
98;
99;
100;
101;
102;8 个数:
59;
60;
61;
62;
63;
64;
65;
66;25 个数:
8;
9;
10;
11;
12;
13;
14;
15;
16;
17;
18;
19;
20;
21;
22;
23;
24;
25;
26;
27;
28;
29;
30;
31;
32;
{
int sum = 0;
for( int X = 1 ; X < 500 ; X ++ )
{
for( int step = 0 ; step < n ; step ++ )
{
sum += X + step;
}
if( sum == 500 )
{
Console.WriteLine( n.ToString() + " 个数: " );
for( int step = 0 ; step < n ; step ++ )
{
Console.WriteLine( Convert.ToString( X + step ) + ";" );
}
break;
}
sum = 0;
}
}测试结果如下:
5 个数:
98;
99;
100;
101;
102;8 个数:
59;
60;
61;
62;
63;
64;
65;
66;
25 个数:
8;
9;
10;
11;
12;
13;
14;
15;
16;
17;
18;
19;
20;
21;
22;
23;
24;
25;
26;
27;
28;
29;
30;
31;
32;
用我的方法,如果扩大外面的循环到5000,就能得到这一组数据for(int n=2;n<5000;n++)
{
float fx=(1000.0f/(n+1)-n)/2; //看fx是不是整数
int x=(int)Math.Floor(fx); //取fx的整数 if((fx-x)<0.000001) //比较fx和x是否一样大小
{
Console.WriteLine("从{0}开始,{1}结束",x,n+x);
}
}
如果delta 是奇数,则 delta +1 是偶数, 2 * a + delta 是奇数所以必须一项偶数,一项奇数分解,过滤后得到
(2*a+delta) * (delta + 1)
-------------------------
(2^0 * 5^0) * (2^3 * 5^3) -> -499到 500
(2^0 * 5^1) * (2^3 * 5^2) -> -97 到 102
(2^0 * 5^2) * (2^3 * 5^1) -> -7 到 32
(2^0 * 5^3) * (2^3 * 5^0) -> 59 到 66(2^3 * 5^0) * (2^0 * 5^3) -> -58 到 66
(2^3 * 5^1) * (2^0 * 5^2) -> 8 到 32
(2^3 * 5^2) * (2^0 * 5^1) -> 98 到 102
(2^3 * 5^3) * (2^0 * 5^0) -> 500 到 500所以一共有 8 组解
我们也用数学推导出来的呀,要是题名改了,求连续整数和等于499的所有连续整数,你的方法还行吗?
我们也用数学推导出来的呀,要是题名改了,求连续整数和等于499的所有连续整数,你的方法还行吗?=============================================================你那只是简化了算法,算不上推导。如果没有计算机/计算器,那你的方法会比挑刺的快吗?数学不是靠蛮力的。
(a+b)(a-b+1)=1000
假设a-b=D
则有:
(2a+D)(D+1)=1000
如果:D为奇数-->2a+D为奇数 且D+1为偶数;
如果:D为偶数-->2a+D为偶数 且D+1为奇数;
也就是说只可能出现一个奇数和一个偶数相乘的情况;
又:
1000=10*10*10=2*5*2*5*2*5=2*2*2*5*5*5
只有以下情况:
5*200
25*40
125*8
接下来可以得到:
a=98 D=4
a=8 D=24
a=59 D=7
当然求为负数的也可以这样做的.
其实扩大到1000(500*2)就够了,1000之外不可能有了,1000之外,两头至少有一头肯定有绝对值大于500的数,也就是数其他绝对值小于500的连续数必须用相反数抵消
{
class mianshi
{
public mianshi()
{
string str = "";
int sum=0;
for (int i=-500;i<=500;i++)
{
for (int j=i;j<=500;j++)
{
sum=(j-i+1)*(i+j)/2;
if (sum==500)
{
str += "第一个数是:" + Convert.ToString(i) + "最后一个数是:" + Convert.ToString(j) + "\n";
}
}
}
System.Windows.Forms.MessageBox.Show(str);
}
}
}
f为起始数字,n为数字个数
则(f+f+n-1)*n/2=500 f=(1000/n+1-n)/2 只考虑f>0,因为f<0的结果可以由f>0的结果一一对应出来,所以n(n-1)<1000所以n<33
不管n为奇数或者偶数,1000应该可以被n整除,即n应该是1000的约数
假如n为偶数,那么n应该是4的倍数(因为500为偶数,不可能有两个奇数的乘积等于偶数
假如n为奇数那么n应该是5(最小奇数约数)的倍数,且f为偶数假如结果和不是偶数,而是奇数R,那么根据(f+f+n-1)*n/2=R,2f+n-1和n/2都应该是奇数,所以n应该是2的倍数,但不应该是4的倍数,所以n应该是2,然后是R的最小奇数公约数,这样算法还可以继续推理...有谁写进一步的算法?
for (int i=0; i<500;i++)
{
int tmp ;
tmp = i;
j = i;
while ( ++j<500)
{
tmp += j;
if (tmp== 500)
{
for (;i<=j;i++)
System.Console.Write("{0},",i);
System.Console.Write("\n");
}
if (tmp >500) break;
}
}
}
=================================================================================
我也不懂。谁可以解释下。
正如1+2++100为(1+100)*100/2一样此处将i+n替换为j,即(i+j)*(j-i+1)/2
int sum=0;
for (int i=-250;i<=250;i++)
{
for (int j=i;j<=250;j++)
{
sum=(j-i+1)*(i+j)/2;
if (sum==500)
{
str = "第一个数是:" + Convert.ToString(i) + "最后一个数是:" + Convert.ToString(j) + "\n";
RT_Sum.AppendText(str);//RT_Sum为RichTextBox
}
}
}
2、b未知是奇是偶的情况下,delta为偶数,无法确认a是否是偶数,但是如果b为奇数,则a一定为奇数,而b为偶数,则a一定为偶数:
原因:
如果(奇数b-奇数c)>0,如果奇数b=2X+1;奇数c=2Y+1,则(奇数b-奇数c)=(2X+1)-(2Y+1)=2(X-Y)——一定为偶数
c、如果(偶数b-偶数c)>0,如果偶数b=2X;偶数c=2Y,则(偶数b-偶数c)=(2X)-(2Y)=2(X-Y)——一定为偶数
for(int i=2;i<=10000;i++)
{
int []Res=new int[i];
int Middle=0;
if(i%2==0)
{
if(500%(i/2)>0||500%i==0) continue;
}
else
{
if(500%i>0) continue;
}
Middle=(int)(500/i);
for(int j=0;j<i;j++)
{
Res[j]=Middle-(int)(i/2)-(i%2)+1+j;
}
}
{
long nNum=0;
for(unsigned long nB=0;nB<1300000000;nB++)
{
double x0=(500-(double(nB)+1)*double(nB)/2)/(double(nB)+1);
if (x0==long(x0))
{
nNum++;
printf("第%d个解答:",nNum);
printf("%d ",long(x0));
printf("%d ",long(x0+nB));
printf("\n\n");
}
}
printf("在%d范围内,解得情况:共有%d组解。\n",nB,nNum);
return 0;
}
这道题目如果用穷举一定是错的!!因为证明边界的过程中顺便就能把结果一起给证了。