九度OJ 1402(计数) 1403(模拟) 1404(未完成) 1405(未完成) 1406(最短路)


1402:特殊的数

题意

现在有n个数,其中有一些出现了一次,一些出现了两次,一些出现了很多次。现在要求你找出那些只出现一次的数,并按升序输出。

思路

由于每个数字的大小范围[1, 1000000],可以开一个这样大的数组统计每个数的出现此处即可。

代码

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

#define N 1000000

int main(void)
{
    int n, i;
    int a, time;
    char count[N+1];

    while (scanf("%d", &n) != EOF)
    {
        memset(count, 0, sizeof(count));
        for(i=1; i<=n; i++)
        {
            scanf("%d", &a);
            if (count[a] <= 1)
                count[a] ++;
        }
        time = 0;
        for (i=1; i<=N; i++)
        {
            if (count[i] == 1)
                time ++;
        }
        printf("%d\n", time);
        if (time == 0)
            continue;
        int first = 1;
        for (i=1; i<=N; i++)
        {
            if (count[i] == 1)
            {
                if (first)
                    first = 0;
                else
                    printf(" ");
                printf("%d", i);
            }
        }
        printf("\n");
    }

    return 0;
}
/**************************************************************
    Problem: 1402
    User: liangrx06
    Language: C
    Result: Accepted
    Time:1540 ms
    Memory:1820 kb
****************************************************************/

1403:神奇的开关

题意

在一个密闭的房间里,里面有n盏,编号从1到n。所有的灯都和4个开关相连,不过4个开关不是普通的开关。
开关1:当开关被按下,所有的灯都改变状态。
开关2:当开关被按下,所有编号为奇数的灯改变状态。
开关3:当开关被按下,所有编号为偶数的灯改变状态。
开关4:当开关被按下,所有编号为(3 * K + 1)(K>=0)的灯改变状态。如1,4,7……
现在有一个计数器C记录所有开关被按的次数的总和。
一开始,所有的灯都是开的,计数器清零。
现在告诉你计数器C记录的次数和一些灯最后的状态,要求你输出所有灯最后可能的状态。Hint:样例输出有更详细的解释。

思路

每种开关不管按下多少次,都等同于两种情况:没有按下或者按下一次。所以四个开关对应于16种情况。遍历这16种情况,看是否符合题目给定的条件即可。

代码

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

#define N 100

int endState(int swit[], int i)
{
    int begin = 1;
    begin ^= swit[0];
    if ((i&1) == 1)
        begin ^= swit[1];
    else
        begin ^= swit[2];
    if (i%3 == 1)
        begin ^= swit[3];
    return begin;
}

int cmp(const void *a, const void *b)
{
    return strcmp((char *)a, (char *)b);
}

int main(void)
{
    int n, c, i, j, k;
    int state[N+1], swit[4];
    char pos[16][N+1];
    int count;

    while (scanf("%d%d", &n, &c) != EOF)
    {
        for (i=1; i<=n; i++)
            state[i] = -1;
        while (scanf("%d", &k) != EOF)
        {
            if (k == -1)
                break;
            state[k] = 1;
        }
        int flag = 1;
        while (scanf("%d", &k) != EOF)
        {
            if (k == -1)
                break;
            if (state[k] == 1)
                flag = 0;
            state[k] = 0;
        }
        if (flag == 0)
        {
            printf("IMPOSSIBLE\n");
            continue;
        }

        count = 0;
        for (j = 0; j < 16; j ++)
        {
            swit[0] = j&1;
            swit[1] = (j>>1)&1;
            swit[2] = (j>>2)&1;
            swit[3] = (j>>3)&1;
            //printf("%d %d %d %d\n", swit[0], swit[1], swit[2], swit[3]);
            for (i=1; i<=n; i++)
            {
                if (state[i] != -1)
                {
                    //printf("i=%d, state[i]=%d, end=%d\n", i, state[i], endState(swit, i));
                    if (endState(swit, i) != state[i])
                        break;
                }
            }
            int minC = swit[0] + swit[1] + swit[2] + swit[3];
            if (i > n && c >= minC && (c-minC)%2 == 0 )
            {
                for (i=1; i<=n; i++)
                {
                    if (state[i] == -1)
                        sprintf(pos[count]+i-1, "%d", endState(swit, i));
                    else
                        sprintf(pos[count]+i-1, "%d", state[i]);
                }
                pos[count][n] = '\0';
                count ++;
            }   
        }   

        if (count == 0)
            printf("IMPOSSIBLE\n");
        else
        {
            qsort(pos, count, sizeof(pos[0]), cmp);
            for (i=0; i<count; i++)
            {
                if (i > 0 && strcmp(pos[i], pos[i-1]) == 0)
                    continue;
                printf("%s\n", pos[i]);
            }
        }   
    }       

    return 0;
}
/**************************************************************
    Problem: 1403
    User: liangrx06
    Language: C
    Result: Accepted
    Time:10 ms
    Memory:916 kb
****************************************************************/

1404:机器人网店

题意

ID为TMao的淘宝用户前些日子在淘宝机器人网店购买了一个智能机器人oz.这个机器人不仅精致小巧,还具有很多有意思的功能。
比如:oz可以在迷宫里自由的上下左右走动; 并且,在不碰到障碍物的情况下,它能够以最短时间从入口处走到出口 (假设存在的话); 最智能的是,在有充电器的地方oz还可以给自己充电 (^_^)。
现在,TMao设计了很多种迷宫,并且在里面随意的摆了些充电器,想请你们帮他算下,这个智能机器人要多久时间可以走出去呢?
他做了如下假设:
1.迷宫可以看作是长为w,宽为h的网格;
2.机器人每移动一步,需要时间1s,消耗电量0.5格;
3.机器人初始电量为满格4格;
4.每个充电器充电次数不限 (充电时间所需时间忽略不计),机器人可以反复经过一个地方,但是不能走到有障碍的地方,并且一旦机器人电量变为0,它就只能停下来,哪怕这个位置正好有充电器,它也没有足够的电量去执行充电操作;
5.机器人走到迷宫出口,必须至少还有0.5格电量,否则也算没走出出口。

思路

稍微麻烦一点的BFS,但我可能忽略了一些细节,导致还没有AC

代码


1405:店小二的IDEA

题意

亲,你们可知淘宝目前每天活跃数据量超过50TB,每天有超过4000万人次的访问,大约要处理几亿次的用户行为。面对如此巨大的数据访问量,淘宝利用oracle RAC系统,构建自己的数据库奇迹。
现在淘宝店小二YY有个想法,如何把一段信息最大限度的压缩,例如字符串abababab就可以看成是abab和abab的连接,在库中可以用串abab2来表示,但是你会发现这个压缩串并不是最好的,可以进一步压缩成ab4。
需要注意的是优秀的压缩算法,在获取高压缩率的同时,也会耗费大量的cpu资源。淘宝是一个讲究实际效益的公司,在带宽资源能够承受的前提下,也需要权衡cpu的消耗,因此淘宝最终的压缩算法,仅仅只将原始串,压缩为一个由字符串和数字构成的形式,详细见题目Hint。

思路

看代码提交AC率只有十分之一给吓住了,目前还没有尝试。

代码


1406:上班啦

题意

淘小宝最近进入了杭州淘宝实习了,可是他所住的地方离工作地点很远(为了省钱)。虽说杭州是个美丽的旅游城市,可是其公共交通却十分被人诟病,早高峰的时间,汽车跟爬的一样,所以经过一个星期的折腾之后,淘小宝决定骑车前往公司上班。
为了每天尽可能的节约体力,同时更多地领略杭州城市的美丽风光,淘小宝就想请你告诉他,从他的住所出发,最短的骑车距离是多少?同时,也请你告诉他,在骑车路径最短的前提下,他有多少种不同的选择?
我们已知淘小宝将整个城市交通按照各个路口以及路口间的道路,抽象成一幅由N 个点与M 条边组成的地图,同时也告知你这些边之间距离,请你告诉淘小宝,最短的骑车距离是多少以及这样长度的不同路径条数。若路径不存在,则按样例输出一行两个-1。

思路

最短路径问题,用dijkstra算法即可解决。

代码

#include <stdio.h>
#include <limits.h>
 
#define N 500
#define INF (INT_MAX/2)
 
int n;
int v[N];
int d[N];
int c[N];
int p[N][N];
 
void init()
{
    int i, j;
    for (i=0; i<n; i++)
    {
        v[i] = 0;
        d[i] = INF;
        c[i] = 0;
        for (j=0; j<n; j++)
            p[i][j] = INF;
    }
}
 
void printDij()
{
    for (int i=0; i<n; i++)
        printf("%d ", d[i]);
    printf("\n");
}
 
void dij(int k)
{
    int i;
    v[k] = 1;
    d[k] = 0;
    c[k] = 1;
    while(k != n-1)
    {
        for (i=0; i<n; i++)
        {
            if (!v[i])
            {
                if (p[i][k] + d[k] < d[i])
                {
                    d[i] = p[i][k] + d[k];
                    c[i] = c[k];
                }
                else if (p[i][k] + d[k] == d[i])
                    c[i] += c[k];
            }
        }
        int md = INF;
        for (i=0; i<n; i++)
        {
            if (!v[i] && d[i] < md)
            {
                k = i;
                md = d[i];
            }
        }
        if (md == INF)
            break;
        v[k] = 1;
        //printDij();
        if (k == n-1)
            break;
    }
}
 
int main()
{
    int i, m, a, b, t;
    while(scanf("%d%d", &n, &m) != EOF)
    {
        init();
        for (i=0; i<m; i++)
        {
            scanf("%d%d%d", &a, &b, &t);
            if (t < p[a-1][b-1])
                p[a-1][b-1] = p[b-1][a-1] = t;
        }
        dij(0);
        if (d[n-1] == INF)
            printf("-1 -1\n");
        else   
            printf("%d %d\n", d[n-1], c[n-1]);
    }               
    return 0;   
}
/**************************************************************
    Problem: 1406
    User: liangrx06
    Language: C
    Result: Accepted
    Time:40 ms
    Memory:1896 kb
****************************************************************/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值