最近复习的一些算法题

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
//Console.WriteLine(ConsleA(7));
//Console.ReadKey();
//Start4();
//StartGreed();
//StartEightQuenn();
//Test2();
//Start1();
//Console.WriteLine(Atoi("- 42"));
StartQuickSort(new int[] { 3, 3, 8, 6, 7, 1, 9, 5, 3, 2, 5, 4, 3 });
Console.ReadKey();
}

    //传入奇数
    #region 输入A
    static string ConsleA(int num)
    {
        if (num % 2 == 0)
        {
            Console.WriteLine("必须传入奇数");
            return "";
        }
        if (num == 1)
        {
            return "A";
        }

        int middle = (num - 1) / 2;
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < num; i++)
        {
            //前面的空格
            result.Append(GetSB(num - 1 - i, " "));
            //第一个A
            result.Append("A");
            //中间的空格
            //看是否为中间数
            if (i == middle)
            {
                result.Append(GetSB(num - 1, "A"));//输入A
            }
            else if (i > 0)
            {
                result.Append(GetSB(2 * (i - 1) + 1, " "));//输入空格
                result.Append("A");
            }
            result.Append('\n');
        }
        return result.ToString();
    }

    static StringBuilder GetSB(int num, string content)
    {
        StringBuilder s = new StringBuilder(); ;
        for (int i = 0; i < num; i++)
        {
            s.Append(content);
        }
        return s;
    }
    #endregion

    #region 插入排序
    //    给定N个矩形,每个矩形宽W米高H米
    //请按以下规则将这N个矩形排序,输出排序后的矩形列表

    //排序规则:
    //面积小的矩形排在面积大的矩形前面
    //面积相同的矩形,按照宽高比排序,宽高比大的矩形排在宽高比小的矩形前面
    //宽高比的定义为 min(W/H, H/W)
    //面积和宽高比都相同的矩形,按照宽排序,宽度更小的矩形排在宽度更大的矩形前面
    //        输入描述:
    //每组输入两行输入
    //第一行是一个整数N (0 < N <= 100)
    //第二行是2* N个整数,分别是每个矩形的宽W和高H,(0 < W,H <= 100)
    //输出描述:
    //每组数据输出一行,2*N个整数,分别是排序后的每个矩形的宽W和高H
    //输入例子1:
    //2
    //2 2 1 1
    //输出例子1:
    //1 1 2 2

    //总结:插入排序
    static void Start()
    {
        string numStr = Console.ReadLine();
        int num = int.Parse(numStr);
        string numArrStr = Console.ReadLine();
        string[] numArr = numArrStr.Split(' ');
        int[] nums = new int[num * 2];
        for (int i = 0; i < numArr.Length; i++)
        {
            nums[i] = Convert.ToInt32(numArr[i]);
        }

        int[] reslut = Test1(num, nums);
        for (int i = 0; i < reslut.Length; i++)
        {
            Console.Write(reslut[i]);
            Console.Write(" ");
        }
    }

    static int[] Test1(int num,
                       int[] nums)
    {
        if (nums.Length / num != 2)
        {
            Console.WriteLine("输入不正确");
            return null;
        }

        int leftIdx = 0;
        int minIdx = 0;
        for (int i = 0; i < num; i++)
        {
            leftIdx = i;
            minIdx = i;
            while (leftIdx > 0)
            {
                leftIdx--;
                int w = nums[2 * (minIdx)];
                int h = nums[2 * (minIdx) + 1];

                int leftW = nums[leftIdx * 2];
                int leftH = nums[2 * leftIdx + 1];

                int curArea = Area(w, h);
                int leftArea = Area(leftW, leftH);

                float curRatio = WHRatio(w, h);
                float leftRatio = WHRatio(leftW, leftH);

                if (leftArea > curArea)
                {
                    Swap(nums, minIdx, leftIdx);
                    minIdx = leftIdx;
                }
                else if (curArea == leftArea)
                {
                    if (curRatio > leftRatio)
                    {
                        Swap(nums, minIdx, leftIdx);
                        minIdx = leftIdx;
                    }
                    else if (curRatio == leftRatio)
                    {
                        if (leftW > w)
                        {
                            Swap(nums, minIdx, leftIdx);
                            minIdx = leftIdx;
                        }
                    }
                }
            }
            //Swap(nums, i, minIdx);
        }

        return nums;
    }

    public static int Area(int W, int H)
    {
        return W * H;
    }

    public static float WHRatio(float W, float H)
    {
        return Math.Min(W / H, H / W);
    }
    //插入
    public static void Swap(int[] arr, int curIdx, int instTarIdx)
    {
        if (arr.Length < 2 || curIdx < 1)
        {
            return;
        }

        int index = curIdx - 1;
        int w = arr[2 * curIdx];
        int h = arr[2 * curIdx + 1];

        while (index >= instTarIdx)
        {
            int oldW = arr[2 * index];
            int oldH = arr[2 * index + 1];
            arr[2 * (index + 1)] = oldW;
            arr[2 * (index + 1) + 1] = oldH;
            index--;
        }
        arr[2 * instTarIdx] = w;
        arr[2 * instTarIdx + 1] = h;
    }
    #endregion

    #region 动态规划
    //钱老板去国外度了个假,刚回到公司就收到了 n 封催促工作完成的邮件。
    //每项工作都有完成截止日期 deadline,钱老板做每项工作都会花去cost天,而且不能中断。
    //请你帮钱老板安排一下完成工作的顺序,以减少总的工作推迟时间。
    //3
    //3 3
    //8 1
    //3 2
    static void Start4()
    {
        string numStr = Console.ReadLine();
        int num = int.Parse(numStr);
        int[,] nums = new int[num, 2];
        for (int i = 0; i < nums.Length; i++)
        {
            string numArrStr = Console.ReadLine();
            string[] numArr = numArrStr.Split(' ');
            for (int j = 0; j < numArr.Length; j++)
            {
                nums[i, j] = Convert.ToInt32(numArr[j]);
            }
        }
        int reslut = Dps2(nums);
        Console.WriteLine(reslut);
    }

    static int Dps2(int[,] arr)
    {
        int minDeadline = int.MaxValue;
        for (int i = 0; i < arr.Length; i++)
        {
            int deadLine = arr[i, 0];
            int cost = arr[i, 1];
            if (arr.Length - 1 > 0)
            {
                //创建一个新的数组
                int[,] residue = new int[arr.Length - 1, 2];
                int index = 0;
                for (int j = 0; j < arr.Length; j++)
                {
                    if (j != i)
                    {
                        residue[index, 0] = arr[j, 0];
                        residue[index, 1] = arr[j, 1];
                        index++;
                    }
                }
                int reslut = Dps2(residue) + (deadLine - cost);
                minDeadline = reslut < minDeadline ? reslut : minDeadline;
            }
        }
        return minDeadline;
    }

    //有一书店引进了一套书,共有3卷,每卷书定价是60元,书店为了搞促销,推出一个活动,活动如下:
    //如果单独购买其中一卷,那么可以打9.5折。
    //如果同时购买两卷不同的,那么可以打9折。
    //如果同时购买三卷不同的,那么可以打8.5折。
    //如果小明希望购买第1卷x本,第2卷y本,第3卷z本,那么至少需要多少钱呢?(x、y、z为三个已知整数)。
    static void Start3()
    {
        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
        sw.Start();
        Console.WriteLine(Dps(90, 2000, 30));
        sw.Stop();
        Console.WriteLine(sw.Elapsed.TotalSeconds);
    }

    //保存运算过程
    static Dictionary<string, int> minMoney = new Dictionary<string, int>();
    static int Dps(int x, int y, int z)
    {
        if (minMoney.ContainsKey(x + "," + y + "," + z))
        {
            return minMoney[x + "," + y + "," + z];
        }
        if (x == y && y == z && z == 1)
        {
            return (int)(180 * 0.85);
        }
        else if (x + y + z == 2)
        {
            if (x == 2 || y == 2 || z == 2)
            {
                return (int)(120 * 0.95);
            }
            else
            {
                return (int)(120 * 0.9);
            }
        }
        else if ((x + y + z) == 1)
        {
            return (int)(60 * 0.95);
        }

        //首选一次性购买三种,不行就一次性买两种
        //最后才选择买一种的
        //每次有7种选择办法
        int s1, s2, s3, s4, s5, s6, s7;
        s1 = s2 = s3 = s4 = s5 = s6 = s7 = int.MaxValue;
        if (x - 1 >= 0 && y - 1 >= 0 && z - 1 >= 0)
            s1 = Dps(x - 1, y - 1, z - 1) + (int)(180 * 0.85);
        else if (z - 1 >= 0 && y - 1 >= 0)
            s2 = Dps(x, y - 1, z - 1) + (int)(120 * 0.9);
        else if (x - 1 >= 0 && z - 1 >= 0)
            s3 = Dps(x - 1, y, z - 1) + (int)(120 * 0.9);
        else if (x - 1 >= 0 && y - 1 >= 0)
            s4 = Dps(x - 1, y - 1, z) + (int)(120 * 0.9);
        else
        {
            if (z - 1 >= 0)
                s5 = Dps(x, y, z - 1) + (int)(60 * 0.95);
            if (x - 1 >= 0)
                s6 = Dps(x - 1, y, z) + (int)(60 * 0.95);
            if (y - 1 >= 0)
                s7 = Dps(x, y - 1, z) + (int)(60 * 0.95);
        }

        int[] arr = new int[] { s1, s2, s3, s4, s5, s6, s7 };
        Array.Sort(arr);
        minMoney.Add(x + "," + y + "," + z, arr[0]);
        return arr[0];
    }

    static void BuleSort(int[] arr)
    {
        for (int i = 0; i < arr.Length - 1; i++)
        {
            for (int j = i + 1; j < arr.Length; j++)
            {
                if (arr[j] < arr[i])
                {
                    int temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
    }
    #endregion

    #region 一封奇怪的信
    //现在你需要用一台奇怪的打字机书写一封书信。信的每行只能容纳宽度为100的字符,也就是说如果写下某个字符会导致行宽超过100,那么就要另起一行书写
    //信的内容由a-z的26个小写字母构成,而每个字母的宽度均会事先约定。例如字符宽度约定为[1, 2, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5],那么就代表'a'到'd'四个字母的宽度分别是1,2,3,4,而'e'到'z'的宽度均为5
    //那么按照上述规则将给定内容S书写成一封信后,这封信共有几行?最后一行宽度是多少?
    static List<char> allLetter = new List<char> { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'

};
static void Start1()
{
//26个字母宽度数组
string numArrStr = Console.ReadLine();
string[] numArr = numArrStr.Split(’ ');
int[] nums = new int[numArr.Length];
for (int i = 0; i < numArr.Length; i++)
{
nums[i] = int.Parse(numArr[i]);
}
string s = Console.ReadLine();
Test1(nums, s);
}

    //要考虑当前这行写下不
    static void Test1(int[] nums, string s)
    {
        //所有字得宽度
        int allLength = 0;
        int lineNumber = 1;
        int lastLineLength = 0;
        var strArr = s.ToArray();
        for (int i = 0; i < strArr.Length; i++)
        {
            char letter = strArr[i];
            int idx = allLetter.IndexOf(letter);
            int length = nums[idx];
            if (100 - (allLength % 100) < length)
            {
                allLength += 100 - (allLength % 100);
            }
            allLength += length;
            if (allLength / 100 > 0)
            {
                lineNumber = allLength / 100 + 1;
            }
            lastLineLength = allLength % 100;
        }
        Console.WriteLine(lineNumber + " " + lastLineLength);
    }
    #endregion

    #region 贪心算法
    //假设有如下课程,希望尽可能多的将课程安排在一间教室里:
    //课程 开始时间    结束时间
    //美术	 9AM	   10AM
    //英语	 9:30AM	   10:30AM
    //数学	 10AM	   11AM
    //计算   10:30AM   11:30AM
    //音乐	 11AM	   12PM
    static void StartGreed()
    {
        string numStr = Console.ReadLine();
        int num = int.Parse(numStr);
        float[][] nums = new float[num][];
        for (int i = 0; i < nums.Length; i++)
        {
            string numArrStr = Console.ReadLine();
            string[] numArr = numArrStr.Split(' ');
            nums[i] = new float[2];
            for (int j = 0; j < numArr.Length; j++)
            {
                nums[i][j] = Convert.ToSingle(numArr[j]);
            }
        }
        Greed(nums);
    }

    //贪婪策略越早开始越早结束越好
    static void Greed(float[][] arr)
    {
        List<float[]> reslut = new List<float[]>();
        for (int i = 0; i < arr.Length; i++)
        {
            //首先对数组重新排序
            for (int j = 0; j < i; j++)
            {
                if (arr[i][0] < arr[j][0] || (arr[i][0] == arr[j][0] && (arr[i][1] - arr[i][0]) < (arr[j][1] - arr[j][0])))
                {
                    int idx = i;
                    //j到i-1的数都向后移移一位
                    //i的数移到j的位置
                    while (idx >= j)
                    {
                        arr[idx + 1] = arr[idx];
                        idx--;
                    }
                    arr[j] = arr[i];
                }
            }
        }

        //然后按照贪心策略:越早开始越早结束
        int index = 0;
        reslut.Add(arr[0]);
        float minInterval = (float)int.MaxValue;
        while (index < arr.Length)
        {
            float[] curCls = reslut[reslut.Count - 1];
            float end = curCls[1];
            //当前时间的开始和之前的结束进行比较
            float curInterval = arr[index][0] - end;
            if (curInterval < minInterval && curInterval >= 0)
            {
                minInterval = arr[index][1] - end;
                reslut.Add(arr[index]);
            }
            index++;
        }
        foreach (var item in reslut)
        {
            Console.WriteLine(item[0] + " " + item[1]);
        }
    }

    static void InsterSort(int[][] arr)
    {
        for (int i = 0; i < arr.Length; i++)
        {
            for (int j = 0; j < i; j++)
            {
                //当前检测到的(相对于是最右边的比较小 i)
                if (arr[i][0] < arr[j][0])
                {
                    int idx = i;
                    //j到i-1的数都向后移移一位
                    //i的数一刀j的位置
                    while (idx >= j)
                    {
                        arr[idx + 1] = arr[idx];
                        idx--;
                    }
                    arr[j] = arr[i];
                }
            }
        }
    }
    #endregion

    #region 回溯算法八皇后算法
    //在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,
    //即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
    static void StartEightQuenn()
    {
        string numStr = Console.ReadLine();
        int num = int.Parse(numStr);
        int[][] nums = new int[num][];
        for (int i = 0; i < num; i++)
        {
            nums[i] = new int[num];
        }

        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
        sw.Start();
        EightQueen(num, 0, nums);
        sw.Stop();
        Console.WriteLine(sw.Elapsed.TotalSeconds);
    }
    static int sum = 0;
    static void EightQueen(int n, int line, int[][] arr)
    {
        //从零开始算
        if (line >= n)
        {
            sum += 1;
            //打印
            //for (int j = 0; j < n; j++)
            //{
            //    for (int k = 0; k < n; k++)
            //    {
            //        Console.Write(arr[j][k]);
            //    }
            //    Console.WriteLine();
            //}
            return;
        }
        for (int i = 0; i < arr.Length; i++)
        {
            //检测这个点是否可以放皇后
            //可以得将继续查找下一行
            if (Check(line, i, arr))
            {
                arr[line][i] = 1;
                EightQueen(n, line + 1, arr);
            }
            //当运行到这行代表未继续向下运行
            //清空当前行棋盘 重新计算上一行
            //此处则代表回溯
            arr[line][i] = 0;
        }
        //代表回到最开始查找,代表已经查找结束
        //输出结果
        if (line == 0)
        {
            Console.WriteLine(sum);
        }
    }
    static bool Check(int line, int row, int[][] arr)
    {
        //判断列
        for (int i = 0; i < line; i++)
        {
            if (arr[i][row] == 1)
            {
                return false;
            }

        }

        //左上
        int x = line - 1, y = row - 1;
        while (x >= 0 && y >= 0)
        {
            if (arr[x][y] == 1)
            {
                return false;
            }
            x -= 1;
            y -= 1;
        }

        x = line - 1;
        y = row + 1;
        while (x >= 0 && y < arr.Length)
        {
            if (arr[x][y] == 1)
            {
                return false;
            }
            x -= 1;
            y += 1;
        }
        //判断斜角方向
        //左上
        if (line - 1 >= 0 && row - 1 >= 0 && arr[line - 1][row - 1] == 1)
        {
            return false;
        }
        //右上
        if (line - 1 >= 0 && row + 1 < arr.Length && arr[line - 1][row + 1] == 1)
        {
            return false;
        }
        return true;
    }
    #endregion

    static void Test2()
    {
        A a = new A();
        Console.WriteLine(sizeof(int));
        Console.WriteLine(sizeof(char));
        Console.WriteLine(sizeof(long));
    }

    //请你来实现一个 atoi函数,使其能将字符串转换成整数。
    //首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。接下来的转化规则如下:
    //如果第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字字符组合起来,形成一个有符号整数。
    //假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成一个整数。
    //该字符串在有效的整数部分之后也可能会存在多余的字符,那么这些字符可以被忽略,它们对函数不应该造成影响。
    //注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换,即无法进行有效转换。
    //在任何情况下,若函数不能进行有效的转换时,请返回 0 。
    //提示:
    //本题中的空白字符只包括空格字符 ' ' 。
    //假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为[−231, 231− 1]。如果数值超过这个范围,请返回 INT_MAX(231 − 1) 或 INT_MIN(−231) 。
    //'0'得ASC码就是0
    static int Atoi(string str)
    {
        if (string.IsNullOrEmpty(str))
        {
            return 0;
        }

        char[] arr = str.ToCharArray();
        int flag = 1;
        int index = 0;
        int result = 0;
        bool isHaveFirst = false;
        while (index < arr.Length)
        {
            char curChar = arr[index];

            if (curChar == ' ' && !isHaveFirst)
            {
                index++;
                continue;
            }
            else if (curChar == '+' && !isHaveFirst)
            {
                index++;
                flag = 1;
                isHaveFirst = true;
                continue;
            }
            else if (curChar == '-' && !isHaveFirst)
            {
                index++;
                flag = -1;
                isHaveFirst = true;
                continue;
            }
            else if ('0' <= arr[index] && arr[index] <= '9')
            {
                break;
            }
            else
                return result;
        }

        while (index < arr.Length)
        {
            if ('0' <= arr[index] && arr[index] <= '9')
            {
                if (result <= (int.MaxValue - (arr[index] - 48)) / 10)
                {
                    result = (result * 10 + arr[index] - 48);
                }
                else
                    return flag > 0 ? int.MaxValue : int.MinValue;
                index++;
            }
            else
                break;

        }

        result = flag * result;
        return result;
    }

    //1.先从数列中取出一个数作为基准数。
    //从右边开始找到比他小的,然后再找左边比他大的(验证过只能从右边开始找)
    //3.目标,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
    ///快速排序
    static void StartQuickSort(int[] arr)
    {
        if (arr == null || arr.Length < 2)
        {
            return;
        }

        int smybol = 0;
        int left = smybol;
        int right = arr.Length - 1;

        QuickSort(arr, left, right);
        for (int i = 0; i < arr.Length; i++)
        {
            Console.Write(arr[i]);
        }
    }

    static void QuickSort(int[] arr, int left, int right)
    {
        if (left >= right)
        {
            return;
        }

        int i = left, j = right;
        int middleVal = arr[left];
        while (i < j)
        {
            while (i < j && arr[j] >= middleVal)
            {
                j--;
            }
            if (i < j && arr[j] < middleVal)
            {
                arr[i] = arr[j];
            }
            while (i < j && arr[i] <= middleVal)
            {
                i++;
            }
            if (i < j && arr[i] > middleVal)
            {
                arr[j] = arr[i];
            }
        }
        arr[i] = middleVal;
        QuickSort(arr, left, i - 1);
        QuickSort(arr, i + 1, right);
    }

    static void ArrSwap(int[] arr, int i, int j)
    {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

class Node
{
    public int vaule;
    public Node next;

    public Node(int va)
    {
        this.vaule = va;
    }
}

class A
{
    public virtual void func() {; }
    float f; char p; int[] adf = new int[3];
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值