主题:一个C#的简单题目.
zjsky830
[专家分:0] 发布于 2007-07-04 23:18:00
给出一个不大于1 000 000的数a。每次操作,你可以将当前的数中的两个非零位交换位置,并都减去1,得到一个新的数。比如155,我们将百位和个位进行操作,就得到了450.请你的程序输出经过任意次上述的操作,a最大能变成什么数。最好运行的速度不超过1秒。
题目不是很难,因为是初学者,想请教下高手如何来写这个程序,谢谢!!
回复列表 (共13个回复)
沙发
zjsky830 [专家分:0] 发布于 2007-07-05 19:55:00
有没有知道的朋友啊,不写出代码也可以提示下大概什么思路来做撒~~~
板凳
淡淡的 [专家分:2030] 发布于 2007-07-09 09:39:00
zjsky830你好,我偶然来到这里,看到你的题目,我不会c#,但可提供一个思路,你不妨试试,
这里假设那个数字是6位数x:
1。把x一位一位地砍到数组里,
d[1]=x的第1位数字; d[2]=x的第2位数字; ...; d[6]=x的第6位数字;
2。按照6个位置任取2个的组合,生成一个数组,或干脆直接赋值
a[1]="12"; a[2]="13"; 。。。a[15]="56";
3。for(i=1;i<16;i++){
e=a[i]的第1位数字;
f=a[i]的第2位数字;
对d[e]和d[f]进行题目的操作,判断是否可生成一个新的数字
}
4。。。。。。。
如果还有什么不清楚,咱们再讨论,祝你编出一个漂亮的程序来。
3 楼
dackula [专家分:60] 发布于 2007-07-09 15:26:00
其中有一个条件没看明白,如果交换的位置正好是0,那么0-1等于什么中间有没有借位的问题,如:505十位与个位交换,并且各减1,那么结果是549还是539
4 楼
szx1999 [专家分:0] 发布于 2007-07-17 10:44:00
给一个粗略的算法:
1. a的各位数字,由高位至低位,存进数组arr[].
2. for(int i=0;i<arr.Length;i++){
if(arr[i]>0)
for(int j=i+1;j<=arr.Length;j++){
2.1 找出从j到arr.Length中的最大数字的序号jmax,并且是最靠后的一个;
2.2 if(arr[i]<arr[jmax]-1)
arr[i]与arr[jmax]减1互换;
}
}
5 楼
szx1999 [专家分:0] 发布于 2007-07-17 10:54:00
[quote]其中有一个条件没看明白,如果交换的位置正好是0,那么0-1等于什么中间有没有借位的问题,如:505十位与个位交换,并且各减1,那么结果是549还是539[/quote]
两个“非零位”交换位置,请仔细看题。
6 楼
louja [专家分:280] 发布于 2007-07-19 13:01:00
/*我写了个从111-1000000中所有数的交换*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace StudyOne
{
class TestClass
{
public void TestMethod()
{
for (int i =111; i <=1000000; i++)
{
//得到一个交换前的数
int[] intSwap = IntArray(i.ToString());
//构造一个存放任意两位数交换后的新数集合
ArrayList al = new ArrayList();
//遍历被交换数的每一位数值,产生任意两个数交换后得到的新数放在集合里面
for (int j = 0; j < intSwap.Length; j++)
{
int temp = intSwap[j];
for (int k = 0; k < intSwap.Length - 1; k++)
{
if (temp!= 0 && intSwap[k+1] != 0)
{
intSwap[j] = intSwap[k + 1] - 1;
intSwap[k + 1] = temp-1;
al.Add(ConstructIntNumber(intSwap));
intSwap = IntArray(i.ToString());
}
}
intSwap = IntArray(i.ToString());
}
Console.Write("数值:{0}任意两位交换后得:",i.ToString());
al.Sort();
foreach (int newData in al)
{
Console.Write(" {0} ", newData);
}
Console.WriteLine();
}
}
public int[] IntArray(string data)
{
char[] beforeSwap = data.ToString().ToCharArray();
int[] intSwap = new int[beforeSwap.Length];
for (int i = 0; i < beforeSwap.Length; i++)
{
intSwap[i] = Convert.ToInt32(beforeSwap[i].ToString());
}
return intSwap;
}
public int ConstructIntNumber(int[] intAl)
{
string number = string.Empty;
for (int i = 0; i < intAl.Length; i++)
{
number += intAl[i].ToString();
}
return Convert.ToInt32(number);
}
}
}
7 楼
louja [专家分:280] 发布于 2007-07-19 17:14:00
/*改了一下*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace StudyOne
{
class TestClass
{
public void TestMethod()
{
for (int i =111; i <=1000000; i++)
{
//得到一个交换前的数
int[] intSwap = IntArray(i.ToString());
//构造一个存放任意两位数交换后的新数集合
ArrayList al = new ArrayList();
//遍历被交换数的每一位数值,产生任意两个数交换后得到的新数放在集合里面
for (int j = 0; j < intSwap.Length; j++)
{
int temp = intSwap[j];
for (int k = j; k < intSwap.Length - 1; k++)
{
if (temp!= 0 && intSwap[k+1] != 0)
{
intSwap[j] = intSwap[k + 1] - 1;
intSwap[k + 1] = temp-1;
al.Add(ConstructIntNumber(intSwap));
intSwap = IntArray(i.ToString());
}
}
intSwap = IntArray(i.ToString());
}
Console.Write("数值:{0}任意两位交换后得:",i.ToString());
al.Sort();
foreach (int newData in al)
{
Console.Write(" {0} ", newData);
}
Console.WriteLine();
}
}
private int[] IntArray(string data)
{
char[] beforeSwap = data.ToString().ToCharArray();
int[] intSwap = new int[beforeSwap.Length];
for (int i = 0; i < beforeSwap.Length; i++)
{
intSwap[i] = Convert.ToInt32(beforeSwap[i].ToString());
}
return intSwap;
}
private int ConstructIntNumber(int[] intAl)
{
string number = string.Empty;
for (int i = 0; i < intAl.Length; i++)
{
number += intAl[i].ToString();
}
return Convert.ToInt32(number);
}
}
}
8 楼
xiaohaokof [专家分:1760] 发布于 2007-07-20 17:36:00
现在题目是这个意思:一个数,交换两个非零数,使之变成“最大”。
我的思路是这样子的:
首先,将个数放到一个数组当中;
然后,从最小位(即个位)开始找起,找到一个最大的数,放到这个临时变量当中temp1;
再者,从最大位(最高位)开始找起,找到一个最小(非零)的数,放到另一个临时变量当中temp2;
最后,将它们(数组)重新组合成一个数,我认为这个数应当就是我们要找的“最大”数了。
如果有什么不当的地方,还请高手指点出来。
9 楼
IIooQ [专家分:0] 发布于 2007-07-21 11:45:00
这个题目,比较复杂的,因为每次交换都有能量损失的,所以,最佳的策略是,尽可能少地减少交换的次数.
正常情况下,在进行一次交换时,存在多种选择,为了避免不必要的能量损失,只能选择使得交换后的值取最大值、且大于当前值的交换,直到,无法找到这样的交换,则,当前值就是所求的最大值.
如果,当前值的由高到低的各个非零数位,恰好是降序排列的,还有必要做交换吗?
如果说:你的目的是,经过无限次的交换<直到不存在这样的交换可能>后的结果,求这样的最大值,那么,问题的关键是考虑,非零数位的值和这些数位的分布情况.总之,是不需要,进行实际的交换运算的.
这是一个策略性问题.
10 楼
xiaohaokof [专家分:1760] 发布于 2007-07-21 13:47:00
我发现这样一个问题,如果说,本身这个数就是最大的,
即,例如:987,这个数本身就是最大了,是不是说就不用交换了,
直接将个位和百位直接各减一就得了。
大家讨论一下!
我来回复