两个思维

Posted wwq-19990526

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了两个思维相关的知识,希望对你有一定的参考价值。

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\n",++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部分,因为青蛙会选择最优策略,则需要看

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\n",++num,ans);
        }
    }
    return 0;
}

 

以上是关于两个思维的主要内容,如果未能解决你的问题,请参考以下文章

这两个代码片段之间有区别吗?如果有,那又如何? [复制]

Android 使用两个不同的代码片段获取当前位置 NULL

13 个非常有用的 Python 代码片段

带有两个列表片段的可滚动布局

显示 ActionBar 选项卡的两个片段

结合两个代码片段?将用户输入的 Youtube url 转换为嵌入 url,然后将 iframe src 替换为转换后的 url