• 两个思维


    1:HDU 5122 K.Bro Sorting

    题目描述:输入T,代表T组样例,每组样例输入n代表n个数,要求进行操作,使n个数为升序排列,求最少操作的次数。

    进行的操作为:对于任意一个数来说,如果它大于等于它右边的数,则交换两数的位置,直到小于右边的数或者到了数组尾部。比如2 5 4 1 3,对第一个数进行操作后,发现顺序不变,依然为2 5 4 1 3,接下来对第二个数进行操作,操作后的顺序为2 4 1 3 5,接下来对第三个数操作,操作后的顺序为2 1 3 4 5,最后再对第一个数进行操作便为1 2 3 4 5。

    思路:为了找到最小操作数,则必须每一个操作的数都一步到位,比如刚刚的例子对于2这个数我们进行了2次操作,虽然第一次为无效操作。

    思维:我们可以按照冒泡的思维来想这题,从数组的后面往前看,当后一个数比前面一个数小时,就进行一次操作,两个数调换,小的就到了前面,大的往后面冒,而且后面都是冒泡好了的序列,所以大数每次往后面冒的时候都会冒到正确的位子,当后一个数比前面一个数小时,此时不用进行操作,只要更新最小值,因为下一次操作比最小值大的数会正确冒到相应位置。

    ac代码(数据有点大要用c输入):

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int a[1000005];
    int main()
    {
        int T,n,num;
        while(~scanf("%d",&T))
        {
            num=0;
            while(T--)
            {
                int ans=0,min;
                scanf("%d",&n);
                for(int i=0;i<n;i++)
                    scanf("%d",&a[i]);
                min=a[n-1];
                for(int i=n-2;i>=0;i--)
                {
                    if(min<a[i])
                        ans++;
                    else
                        min=a[i];
                }
                printf("Case #%d: %d
    ",++num,ans);
            }
        }
        return 0;
    } 

    2:HDU 5037 Frog

    题目描述:在一条长为M的小河里有N个石头,一只每次能够跳L米远的青蛙要过河,现在你可以在河中任意添加石头让青蛙过河,问在青蛙使用最优策略的前提下跳到对岸最多需要多少次?

    输入描述:有T组样例,每组样例先输入N,M,L。在接下来的N行里,每行一个数,代表距离起始岸多少距离处有石头。

    思路:因为青蛙会使用最优策略,故不能每隔1m就添加石头,此时青蛙最多跳(M+L-1)/L次,要想青蛙跳的次数多,我们可以发现,如果两岸距离L+1时,青蛙就得跳两次。所以我们可以将已有的每两个石头之间分成两个部分,一个是距离没有(L+1)的部分(x)和距离有y倍(L+1)的部分,所以无论如何,青蛙在(L+1)部分都要跳两次,总共则会跳2*y次,而在x部分,因为青蛙会选择最优策略,则需要看上一次跳的剩余距离是不是能和这次并起来(即d+x<L),如果能并起来,就先把d和x攒起来;如果不能,则青蛙必须跳一次,同时d更新为这次剩下的x。

    ac代码(数据有点大要用c输入):

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    using namespace std;
    int main()
    {
        int T;
        while(~scanf("%d",&T))
        {
            int N,M,L,num=0;
            int a[200005];
            while(T--)
            {
                scanf("%d %d %d",&N,&M,&L);
                for(int i=1;i<=N;i++)
                    scanf("%d",&a[i]);
                a[0]=0;a[N+1]=M;
                sort(a,a+N+2);
                int ans=0,x,y,d=L;
                for(int i=1;i<=N+1;i++)
                {
                    x=(a[i]-a[i-1])%(L+1);
                    y=(a[i]-a[i-1])/(L+1);
                    if(d+x>L)
                    {
                        ans=ans+2*y+1;
                        d=x;
                    }
                    else
                    {
                        ans=ans+2*y;
                        d+=x;
                    }
                }
                printf("Case #%d: %d
    ",++num,ans);
            }
        }
        return 0;
    }
  • 相关阅读:
    【线程控制:线程休眠】
    【线程调度-优先级】
    【多线程实现方案一:继承Thread 类】
    【多线程概述】
    【使用Mybatis-Generator自动生成Mapper、Model、Mapping相关文件】
    【springmvc集成mybatis框架】
    【UltraISO制作centos7系统安装盘】
    【己有原码, 为何还有反码和补码?】
    【原码, 反码, 补码的基础概念和计算方法】
    【数据类型】
  • 原文地址:https://www.cnblogs.com/wwq-19990526/p/10596923.html
Copyright © 2020-2023  润新知