码迷,mamicode.com
首页 > 其他好文 > 详细

两个思维

时间:2019-03-25 21:58:29      阅读:234      评论:0      收藏:0      [点我收藏+]

标签:添加   ret   行操作   使用   部分   col   cas   位置   turn   

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;
}

 

两个思维

标签:添加   ret   行操作   使用   部分   col   cas   位置   turn   

原文地址:https://www.cnblogs.com/wwq-19990526/p/10596923.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!