九度OJ 1371(排序) 1372(DP) 1373(统计) 1374(统计) 1375(统计)


1371:最小的K个数

http://ac.jobdu.com/problem.php?pid=1371

题意

输入n个整数,找出其中最小的K个数。

思路

排序然后输出。

代码

#include<stdio.h>
#include<algorithm>
#define N 200005
using namespace std;
int main()
{
        int n,k;
        int i;
        int a[N];
        while(scanf("%d%d",&n,&k)!=EOF)
        {
                for(i=0;i<n;i++)
                {
                        scanf("%d",&a[i]);
                }
                sort(a,a+n);
                for(i=0;i<k-1;i++)
                {
                        printf("%d ",a[i]);
                }
                printf("%d\n",a[k-1]);
        }
        return 0;
}
/**************************************************************
    Problem: 1371
    User: liangrx06
    Language: C++
    Result: Accepted
    Time:860 ms
    Memory:1728 kb
****************************************************************/

1372:最大子向量和

http://ac.jobdu.com/problem.php?pid=1372

题意

求向量中连续子向量的最大和,同时求出该子向量的第一个元素的下标和最后一个元素的下标。若是存在多个子向量,则输出起始元素下标最小的那个。

思路

基本DP题。我的代码是学DP之前写的,复杂度与DP都是O(N)。

代码

#include <stdio.h>

int main(void)
{
    int n;
    long long a[1000000];
    int i;
    long long best, bestTmp;
    long long bestL, bestR, bestTmpL, bestTmpR;

    while (scanf("%d", &n) != EOF)
    {
        if (n == 0)
            break;
        for (i=0; i<n; i++)
            scanf("%lld", &a[i]);

        best = a[0];
        bestL = bestR = 0;
        bestTmp = a[0];
        bestTmpL = bestTmpR = 0;
        for (i=1; i<n; i++)
        {
            if (bestTmp < 0)
            {
                bestTmp = a[i];
                bestTmpL = bestTmpR = i;
            }
            else
            {
                bestTmp += a[i];
                bestTmpR = i;
            }
            if (bestTmp > best)
            {
                best = bestTmp;
                bestL = bestTmpL;
                bestR = bestTmpR;
            }
        }

        printf("%lld %lld %lld\n", best, bestL, bestR);
    }

    return 0;
}
/**************************************************************
    Problem: 1372
    User: liangrx06
    Language: C
    Result: Accepted
    Time:470 ms
    Memory:8652 kb
****************************************************************/

1373:整数中1出现的次数

http://ac.jobdu.com/problem.php?pid=1373

题意

输出a和b之间数字1出现的次数。

思路

分别求1-(a-1)和1-b之间1出现的次数,两者想减。

代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int count(char *s, int a)
{
    int n = strlen(s);
    int i;
    int res = 0;
    int pow10i = 1;
    int si;
    for (i=0; i<n; i++)
    {
        res += a/(pow10i*10)*pow10i;
        si = n-1-i;
        if (s[si] > '1')
            res += pow10i;
        if (s[si] == '1')
            res += a%pow10i + 1;
        //printf("i=%d, a=%d, pow10i=%d, res=%d\n", i, a, pow10i, res);
        pow10i *= 10;
    }
    return res;
}

int main()
{
    int i;
    char sa[11], sb[11];
    int a, b;
    while(scanf("%s%s", sa, sb) != EOF)
    {
        a = atoi(sa);
        b = atoi(sb);

        if (a > b)
        {
            int tmp = a;
            a = b;
            b = tmp;
            char stmp[11];
            strcpy(stmp, sa);
            strcpy(sa, sb);
            strcpy(sb, stmp);
        }

        int counta = 0;
        int tmpa = a;
        for (i=0; i<strlen(sa); i++)
        {
            if (tmpa%10 == 1)
                counta ++;
            tmpa /= 10;
        }

        int count0toa = count(sa, a);
        int count0tob = count(sb, b);

        printf("%d\n", count0tob - count0toa + counta);
    }
    return 0;
}
/**************************************************************
    Problem: 1373
    User: liangrx06
    Language: C
    Result: Accepted
    Time:0 ms
    Memory:912 kb
****************************************************************/

1374:所有员工年龄排序

http://ac.jobdu.com/problem.php?pid=1374

题意

公司内员工年龄排序。

思路

此题特点是age取值范围为(1<=age<=99),可用设置一数组统计每个age出现次数。算法复杂度O(N)。
快排估计会超时。

代码

#include <stdio.h>
#include <string.h>

#define N 1000000

int main()
{
    int i, j, n;
    int a[N];
    int count[100];
    while(scanf("%d", &n) != EOF)
    {
        memset(count, 0, sizeof(count));
        for (i=0; i<n; i++)
        {
            scanf("%d", &a[i]);
            count[a[i]] ++;
        }
        for (i=1; i<100; i++)
        {
            for (j=0; j<count[i]; j++)
                printf("%d ", i);
        }
        printf("\n");
    }
    return 0;
}
/**************************************************************
    Problem: 1374
    User: liangrx06
    Language: C
    Result: Accepted
    Time:790 ms
    Memory:4748 kb
****************************************************************/

1375:陈博的完美主义

http://ac.jobdu.com/problem.php?pid=1375

题意

对于一个整数序列d1, d2, d3 … dn,你是否能够算出至少改变其中的几个数,才能把他们变成从1到N的一个排列?

思路

统计1-N中数未出现得个数就是答案。

代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define N 100000
#define M 100

int main()
{
    int i, n;
    int a[N], b[N+1];
    char s[M+1];
    while(scanf("%d", &n) != EOF)
    {
        memset(b, 0, sizeof(b));
        for (i=0; i<n; i++)
        {
            scanf("%s", s);
            if (strlen(s) > 9)
                a[i] = 0;
            else
                a[i] = atoi(s);
            if (a[i] <= n && a[i] >= 1)
                b[a[i]]++;
        }
        int count = 0;
        for (i=1; i<=n; i++)
        {
            if (b[i] > 0)
                count ++;
        }
        printf("%d\n", n-count);
    }
    return 0;
}
/**************************************************************
    Problem: 1375
    User: liangrx06
    Language: C
    Result: Accepted
    Time:170 ms
    Memory:1232 kb
****************************************************************/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值