九度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
****************************************************************/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章