[V0.1.1]Backtrack problem in a 4 - dimensional container

来源:互联网 发布:淘宝搜索关键词排名 编辑:程序博客网 时间:2024/06/07 00:25
 input file:in.txt    output file:out.txt
time limit: 2000ms
language:ASM、C、C++、C#、Java、VB

Difficulty:★★★★
Describe:

    Assume that their are m persons,p cube types and n 3 - dimensional containers.Each cube's length and width are 1 and its height is a positive interger.Each person have several cubes and each cube is belonging to different cube types. Your task is to put these cubes in random different integercoordinates of these container.You should ensure that there isn't any cube which is overlapped with another.
Input:
    The first line:Four integers x,y,z,n(0<x,y,z<50,0<n<10)separated by whitespace,denoting the lengths of the 3 - dimensional container on each dimensional and the count of containers;

    The following n lines:A single string,denoting the name of each container;

    The following line:A single integer (0<p<50),denoting the number of cube types;
    The following p lines:The name of cube and a integer q(0<q<=z)separated by whitespace,denoting the height of cube;

    The following line:A integer m(0<m<100),denoting the number of persons;
    The following m lines:The name of person and several integer separated by whitespace,denoting the cube types belonging to him. 

Output:
    For each person, print his or her name ,  followed by the corresponding cube coordinates in the format shown in the Sample Output.

    If there is no way to put all the cubes in these containers, output a single line:"No solution!".

Sample Input 1:
2 2 3 2
容器一
容器二
4
第一种方块 2
第二种方块 3
第三种方块 1
第四种方块 2
3
柯南 1 2 3
灰原 3 4
元太 1 2
Sample Output 1:
柯南
第一种方块 容器一(2,1,2)
第二种方块 容器二(1,2,1)
第三种方块 容器一(1,1,2)
灰原
第三种方块 容器二(2,2,1)
第四种方块 容器一(1,2,1)
元太
第一种方块 容器一(2,2,2)
第二种方块 容器二(2,1,1)
Sample Input 2:
2 2 4 1
实验室一
4
J2ME项目设计 1
软件工程实验 2
计算机网络实验 3
算法设计实验 4
3
网络一班 1 2 3
软件一班 1 2
计科一班 1 2 4
Sample Output 2:
网络一班
J2ME项目设计 实验室一(1,2,1)
软件工程实验 实验室一(1,2,2)
计算机网络实验 实验室一(2,2,2)
软件一班
J2ME项目设计 实验室一(1,2,4)
软件工程实验 实验室一(2,1,1)
计科一班
J2ME项目设计 实验室一(2,2,1)
软件工程实验 实验室一(2,1,3)
算法设计实验 实验室一(1,1,1)
Sample Input 3:
2 2 4 1
实验室一
4
J2ME项目设计 1
软件工程实验 2
计算机网络实验 3
算法设计实验 4
3
网络一班 1 2 3
软件一班 2 3
计科一班 1 2 4
Sample Output 3:
No Solution!

Solution:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.IO;namespace RapidPrototyping0_1_1{    class Program    {        //A point in the 4 - dimensional space        struct point4d        {            public int w, x, y, z;            public point4d(int w, int x, int y, int z)            {                this.w = w;                this.x = x;                this.y = y;                this.z = z;            }        }        //The cube with a specific height        struct cube        {            public int height;            public string name;            public int ownerIndex;            public string owner;            public point4d pt;        }        //The 4 - dimensional space        static int[, , ,] space;        //The cube array        static cube[] cubeArray;        //The names of all the 3 - dimensional container        static string[] containerName;        //Entrance        static void Main(string[] args)        {            using (StreamReader sr = new StreamReader("in.txt", Encoding.GetEncoding("GB2312")))            using (StreamWriter sw = new StreamWriter("out.txt"))                Distribute(sr,sw);        }        //Distribute all the cubes in the 4D space        private static void Distribute(StreamReader sr, StreamWriter sw)        {            int i,x, y, z, w, n, m;            string s = sr.ReadLine();            Distribute_wxyz(s,out x,out y,out z,out w);            space = new int[w,x,y,z];            containerName = new string[w];            for (i = 0; i < w; i++) containerName[i] = sr.ReadLine();            n = Convert.ToInt32(sr.ReadLine());            string[] name = new string[n];            int[] height = new Int32[n];            for (i = 0; i < n; i++)            {                string s1 = sr.ReadLine();                Distribute_nameheight(s1,out name[i],out height[i]);            }            m = Convert.ToInt32(sr.ReadLine());            Distribute_SetCube(m, sr, out cubeArray, name, height);            if (Distribute_BackTrack(0)) Distribute_Output(sw);            else sw.WriteLine("No Solution!");        }        //Extract the value of w,x,y and z from the string        private static void Distribute_wxyz(string s, out int x, out int y, out int z, out int w)        {            string[] sarray = s.Split(' ');            x = Convert.ToInt32(sarray[0]);            y = Convert.ToInt32(sarray[1]);            z = Convert.ToInt32(sarray[2]);            w = Convert.ToInt32(sarray[3]);        }        //Extract the value of name and height from the string        private static void Distribute_nameheight(string s1, out string name, out int height)        {            string[] sarray = s1.Split(' ');            name = sarray[0];            height = Convert.ToInt32(sarray[1]);        }        //Create a certain number of cubes and set their attributes        private static void Distribute_SetCube(int m, StreamReader sr, out cube[] cubeArray,string[] name,int[] height)        {            List<cube> cubelist = new List<cube>();            for (int j = 0; j < m; j++)            {                string s = sr.ReadLine();                string[] sArray = s.Split(' ');                string owner = sArray[0];                for (int i = 0; i < sArray.Length - 1; i++)                    cubelist.Add(Distribute_SetCube_New(j, owner, Convert.ToInt32(sArray[i + 1])-1, name, height));            }            cubeArray = Distribute_SetCube_Array(cubelist);            cubeArray = Distribute_SetCube_Remix(cubeArray);        }        //Create a new cube and set its attributes        private static cube Distribute_SetCube_New(int ownindex,string owner, int index, string[] name, int[] height)        {            cube c = new cube();            c.height = height[index];            c.name = name[index];            c.owner = owner;            c.ownerIndex = ownindex;            return c;        }        //Translate the cube list to cube array         private static cube[] Distribute_SetCube_Array(List<cube> cubelist)        {            int count = cubelist.Count;            cube[] cubeArray = new cube[count];            for (int i = 0; i < count; i++) cubeArray[i] = cubelist[i];            return cubeArray;        }        //Calculate the location of all the cubes in 4 - dimensional space using back track algorithm        private static bool Distribute_BackTrack(int p)        {            if (p >= cubeArray.Length) return true;            else            {                point4d[] availableArray = Distribute_BackTrack_Random(cubeArray[p].height);                foreach (point4d pt in availableArray)                {                    bool flag = false;                    Distribute_BackTrack_Load(ref cubeArray[p], pt);                    flag = Distribute_BackTrack(p + 1);                    if (flag) return true;                    else                        Distribute_BackTrack_Unload(cubeArray[p].height, pt);                }            }            return false;        }        //Get all the positions which can put the cube with a specific height and disorganize them        private static point4d[] Distribute_BackTrack_Random(int height)        {            List<point4d> ptlist = new List<point4d>();            for (int i = 0; i < space.GetLength(0); i++)                for (int j = 0; j < space.GetLength(1); j++)                    for (int k = 0; k < space.GetLength(2); k++)                        for (int l = 0; l < space.GetLength(3) - height + 1; l++)                        {                            bool putdownable = true;                            for (int m = 0; m < height; m++)                                if (space[i, j, k, l + m] == 1)                                {                                    putdownable = false;                                    break;                                }                            if (putdownable) ptlist.Add(new point4d(i, j, k, l));                        }            point4d[] pointArray = Distribute_BackTrack_Random_Array(ptlist);            return pointArray;        }        //Translate the point list to point array        private static point4d[] Distribute_BackTrack_Random_Array(List<point4d> ptlist)        {            int count = ptlist.Count;            point4d[] ptArray = new point4d[count];            for (int i = 0; i < count; i++)                ptArray[i] = ptlist[i];            return ptArray;        }        //Disorganize the cube array        private static cube[] Distribute_SetCube_Remix(cube[] cubeArray)        {            int count = cubeArray.Length;            int[] indexArray = new int[count];            cube[] newArray = new cube[count];            for (int i = 0; i < count; i++)            {                indexArray[i] = Distribute_SetCube_Remix_Index(count, i, indexArray);                newArray[i] = cubeArray[indexArray[i]];            }            return newArray;        }        //Get a random index which haven't appeared        private static int Distribute_SetCube_Remix_Index(int count, int i, int[] indexArray)        {            Random r = new Random();            int result;            do            {                result = r.Next(count);            }            while (Distribute_BackTrack_Random_Remix_Index_Exist(result, indexArray,i));            return result;        }        //Check whether the index is exist        private static bool Distribute_BackTrack_Random_Remix_Index_Exist(int result, int[] indexArray, int i)        {            for (; i > 0; i--)                if (indexArray[i - 1] == result)                    return true;            return false;        }        //Put the cube to the specific point of the 4 - dimensional space        private static void Distribute_BackTrack_Load(ref cube cube, point4d pt)        {            for (int i = 0; i < cube.height; i++)            {                space[pt.w, pt.x, pt.y, pt.z + i] = 1;            }            cube.pt = pt;        }        //Remove the specific cube in the 4 - dimensional space         private static void Distribute_BackTrack_Unload(int height, point4d pt)        {            for (int i = 0; i < height; i++)            {                space[pt.w, pt.x, pt.y, pt.z + i] = 0;            }        }        //Output the final result        private static void Distribute_Output(StreamWriter sw)        {            Distribute_Output_SortByOwner(cubeArray);            string owner = "";            for (int i = 0; i < cubeArray.Length; i++)            {                if (cubeArray[i].owner != owner)                {                    owner = cubeArray[i].owner;                    sw.WriteLine(owner);                }                sw.WriteLine(cubeArray[i].name + " " + containerName[cubeArray[i].pt.w]+"("+(cubeArray[i].pt.x+1)+","+(cubeArray[i].pt.y+1)+","+(cubeArray[i].pt.z+1)+")");            }        }        //Ascending sort the cubes by their owners        private static void Distribute_Output_SortByOwner(cube[] cubeArray)        {            for (int i = 0; i < cubeArray.Length-1; i++)            {                for (int j = i + 1; j < cubeArray.Length; j++)                {                    if (cubeArray[i].ownerIndex > cubeArray[j].ownerIndex)                        Distribute_Swap(ref cubeArray[i],ref cubeArray[j]);                }            }        }        //Swap two cube        private static void Distribute_Swap(ref cube cube_1, ref cube cube_2)        {            cube temp = cube_1;            cube_1 = cube_2;            cube_2 = temp;        }    }}


 

原创粉丝点击