using System;
using System.Text.RegularExpressions;
namespace CodeS
{
class Program_1
{
static string test_data = "0 1 0 0 0 1 4 0 0 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0";
static int line = 0;
static int [] data;
static stNode [] stTree;
static int nodeCount = 0;
static int treeMakeIndex = 0;
static bool [] stables;
static sRate [] rateRet;
public struct sRate
{
public int fenzi;
public int fenmu;
}
public struct stNode
{
public int stateId;
public bool bRepeat;
public int [] child;
public int childCount;
public int parent;
public sRate rate;
}
// 生成树
static void MakeTree()
{
stTree = new stNode[nodeCount];
MakeNode(0, -1);
int [] tdata = new int[data.Length];
for(int i = 0; i < data.Length; i++)
tdata[i] = data[i];
for(int i = 0; i < data.Length; i++)
{
if (tdata[i] != 0)
{
MakeNode(i%line, i/line);
}
}
}
// 生成树节点
static void MakeNode(int childId, int parentId)
{
stNode tempNode = new stNode();
tempNode.stateId = childId;
tempNode.parent = parentId;
int index = 0;
bool bExist = FindNode(childId, ref index);
tempNode.bRepeat = bExist;
int sum = 0;
if (parentId >= 0)
{
for(int i = 0; i < line; i ++)
if(data[parentId*line+i] != 0)
{
sum += data[parentId*line+i];
}
tempNode.rate.fenzi = data[parentId*line+childId];
tempNode.rate.fenmu = sum;
}
if (!bExist) // 重复节点,不再添加子节点数据
{
int count = 0;
for(int i = 0; i < line; i ++)
if(data[childId*line+i] != 0)
{
count ++;
}
tempNode.childCount = count;
tempNode.child = new int[count];
int j = 0;
for(int i = 0; i < line; i ++)
if(data[childId*line+i] != 0)
{
tempNode.child[j++] = i;
}
}
stTree[treeMakeIndex ++] = tempNode;
}
// 查找树节点
static bool FindNode(int id, ref int index, bool repeatNode = true)
{
for(int i = 0; i < treeMakeIndex; i ++)
{
if (stTree[i].stateId == id)
{
if((!repeatNode && !stTree[i].bRepeat) || repeatNode)
{
index = i;
return true;
}
}
}
return false;
}
// 判定是否重复节点
static bool RepeatNode(int id)
{
for(int i = 0; i < treeMakeIndex; i ++)
{
if (stTree[i].stateId == id && stTree[i].bRepeat)
{
return true;
}
}
return false;
}
// 逻辑计算主入口
static void DoCal()
{
// 稳定态
stables = new bool[line];
rateRet = new sRate[line];
for(int i = 0; i < line; i ++)
{
int sum = 0;
for(int j = 0; j < line; j ++)
{
sum += data[i*line + j];
}
if (sum == 0)
stables[i] = true;
else
stables[i] = false;
}
for (int i = 0; i < line; i ++)
{
if (stables[i])
{
int index = 0;
bool bExist = FindNode(i, ref index, false);
if (bExist)
{
// 自身节点
CalRate(index, ref rateRet[i].fenzi, ref rateRet[i].fenmu);
// 自身重复节点
for(int j = 0; j < stTree.Length; j ++)
{
int fenzi = 0;
int fenmu = 0;
if (stTree[j].stateId == i && stTree[j].bRepeat)
{
CalRate(index, ref fenzi, ref fenmu);
DoAdd(ref rateRet[i].fenzi, ref rateRet[i].fenmu, fenzi, fenmu);
}
}
// 父节点是重复节点
int parentId = stTree[index].parent;
while(true)
{
if (parentId == -1)
break;
if (RepeatNode(parentId))
{
int pindex = 0;
if(FindNode(parentId, ref pindex, false))
{
int fenzi1 = 0;
int fenmu1 = 0;
CalRate(index, ref fenzi1, ref fenmu1, pindex);
int _fenzi = 0;
int _fenmu = 0;
for (int k = 0; k < treeMakeIndex; k ++)
{
int _fenzi1 = fenzi1;
int _fenmu1 = fenmu1;
if (stTree[k].stateId == parentId && stTree[k].bRepeat)
{
int fenzi2 = 0;
int fenmu2 = 0;
CalRate(k, ref fenzi2, ref fenmu2);
DoMulti(ref _fenzi1, ref _fenmu1, fenzi2, fenmu2);
DoMulti(ref _fenzi1, ref _fenmu1, fenmu2, fenmu2-fenzi2);
DoAdd(ref _fenzi, ref _fenmu, _fenzi1, _fenmu1);
}
}
DoAdd(ref rateRet[i].fenzi, ref rateRet[i].fenmu, _fenzi, _fenmu);
}
}
int _t = 0;
if (FindNode(parentId, ref _t, false))
parentId = stTree[_t].parent;
else
break;
}
//Console.Write(rateRet[i].fenzi); Console.Write('/'); Console.Write(rateRet[i].fenmu); Console.WriteLine();
}
}
}
}
static void CalRate(int index, ref int fenzi, ref int fenmu, int toIndex = 0)
{
if (fenzi == 0) fenzi = 1;
if (fenmu == 0) fenmu = 1;
if (index > 0 && index != toIndex)
{
fenzi *= stTree[index].rate.fenzi;
fenmu *= stTree[index].rate.fenmu;
int pindex = 0;
if (FindNode(stTree[index].parent, ref pindex, false))
{
CalRate(pindex, ref fenzi, ref fenmu, toIndex);
SimpleFenShu(ref fenzi, ref fenmu);
}
}
}
// 分数简化
static void SimpleFenShu(ref int fenzi, ref int fenmu)
{
int temp = Math.Min(fenzi, fenmu);
if (temp > 1)
{
for(int i = 2; i <= temp; )
{
if(temp > 1 && fenzi % i == 0 && fenmu % i == 0)
{
fenzi = fenzi / i;
fenmu = fenmu / i;
i = 2;
temp = Math.Min(fenzi, fenmu);
}
else
i ++;
}
}
}
// 求最小公倍数
static int MinGongBeiShu(int [] input)
{
int max = 0;
int maxGBS = 1;
for(int i = 0; i < input.Length; i ++)
{
if (input[i] > 0)
{
maxGBS *= input[i];
if (max < input[i])
max = input[i];
}
}
int nRet = 0;
if (max > 0)
{
int max_i = maxGBS / max;
for (int i = 1; i <= max_i; i ++)
{
bool bNoRemain = true;
for(int j = 0; j < input.Length; j ++)
{
if (input[j] > 0 && (i*max)%input[j] != 0)
{
bNoRemain = false;
break;
}
}
if (bNoRemain)
{
nRet = i*max;
break;
}
}
}
return nRet;
}
// 分数加法
static void DoAdd(ref int fenzi1, ref int fenmu1, int fenzi2, int fenmu2)
{
if (fenzi1 == 0 || fenzi2 == 0)
{
fenzi1 = fenzi1 + fenzi2;
fenmu1 = fenmu1 + fenmu2;
}
else
{
fenzi1 = fenzi1 * fenmu2 + fenzi2 * fenmu1;
fenmu1 = fenmu1 * fenmu2;
}
SimpleFenShu(ref fenzi1, ref fenmu1);
}
// 分数乘法
static void DoMulti(ref int fenzi1, ref int fenmu1, int fenzi2, int fenmu2)
{
fenzi1 = fenzi1 * fenzi2;
fenmu1 = fenmu1 * fenmu2;
SimpleFenShu(ref fenzi1, ref fenmu1);
}
static void Main(string[] args)
{
// 数据
string [] _s = test_data.Split(' ');
data = new int[_s.Length];
nodeCount = 1;
for(int i = 0; i < _s.Length; i ++)
{
data[i] = int.Parse(_s[i]);
if (data[i] != 0)
nodeCount ++;
//Console.Write(data[i]); Console.Write(' ');
}
line = (int)Math.Sqrt(_s.Length);
// 生成树
MakeTree();
// 算法入口
DoCal();
// 数据规整
int [] outdata = new int[line];
for (int i = 0; i < line; i ++)
{
if (stables[i])
{
int index = 0;
if (FindNode(i, ref index))
{
outdata[i] = rateRet[i].fenmu;
}
}
}
int gbs = MinGongBeiShu(outdata);
// 输出
for (int i = 0; i < line; i ++)
{
if (stables[i])
{
if (outdata[i] > 0)
Console.Write(gbs/rateRet[i].fenmu*rateRet[i].fenzi);
else
Console.Write(0);
Console.Write(' ');
}
}
Console.Write(gbs);
}
}
}
2021-08-29 代码
最新推荐文章于 2024-05-06 22:23:44 发布