1. 程式人生 > >廣工新生賽

廣工新生賽

這是自己第一次打比賽,比賽體驗還是不錯滴,想寫下自己打比賽過程中的想法和錯誤。

第一題 簽到題

題目:奇諾,聽說只要n個連續時刻的速度都嚴格大於零,摩托車就能飛向月球上面誒。
輸入:
第一行輸入一個整數T(T<=10),代表有T組樣例
對於每組樣例:
第一行輸入一個整數n,(1<=n<=100),代表n個連續時刻的速度。
第二行輸入n個整數ai(0<=ai<=100),代表該時刻艾魯梅斯的速度。
輸出:
對於每組樣例:
如果艾魯梅斯能飛往月球就輸出“WeRide.ai”(沒有引號);
否則輸出“Transform Mobility With Autonomous Driving”(沒有引號)。
sample:
input:
2
5
1 2 3 4 5
5
1 2 3 4 0
output:

WeRide.ai
Transform Mobility With Autonomous Driving

#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
    int t,n,a[105],flag,i;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        flag = 0;
        memset(a,0,sizeof(105));
        for(i=0; i<n; i++)
        {
            scanf("%d",&a[i]);
            if(a[i] == 0)
            {
                 flag = 1;
            }
        }
         if(flag)
                printf("Transform Mobility With Autonomous Driving\n");
         else
                printf("WeRide.ai\n");
    }
}

一開始wa了好幾次呀,後來對照輸入輸出和自己的程式碼各種看才發現為了減少時間複雜度在第一個if裡面加了break,導致後面沒得輸入了啊,真是糟糕。。。

第六題 最長連續連號上升子序列

題目:連號的定義是a[i] + 1 == a[i+1],在這樣的定義下長度最少為2,也可能並沒有所謂連號子串,那長度為1就行了
輸入:
第一行一個整數T(T<=15),代表一共有T組樣例。
對於每組樣例:
第一行一個整數 n, 表示序列長度(1 <= n <= 10000)
第二行 n 個整數 a[i]。(0 <= a[i] <= 10000)
題目保證n的總和不超過30000.
輸出:
輸出一個整數,表示最長的連號子串的長度。
sample:
input:
2
5
1 2 3 5 6
3
1 3 2
output:
3
1

#include <cstdio>
#include <algorithm>
int a[10005];
using namespace std;
int main()
{
    int t,i,j,ans,n,maxlist,x;
    scanf("%d",&t);
    while(t--)
    {
       scanf("%d",&n);
       for(i=0; i<n; i++)
       {
           scanf("%d",&a[i]);
       }
       maxlist = 1;
       for(i=0; i<n-1; i++)
       {
           ans = 1;
           for(j=i+1; j<n; j++)
           {
               if(a[j] == a[j-1] + 1)
               {
                   ans++;
                   maxlist = max(maxlist,ans);
               }
               else
                break;
           }
       }
       printf("%d\n",maxlist);
    }
}

這個題一開始寫的時候連本地都沒過,真是氣死人,最長連續上升子序列,之前有做過這種題,但是今天寫來寫去都不對,接近崩潰邊緣……後來對照執行結果和程式碼,一步一步想,終於發現了!是判斷完是否是連號後面忘記加else break!!怪不得第二個sample一直輸出2!!沒加else break就不會停,會繼續往下迴圈,那麼找的就不是連續連號子序列!只是連號子序列沒有連續!!

第七題 是傻逼題呀 小學一年級都會做

題目:如果把自我比作一根繩子,把現實比作一面無限長的筆直的牆,那麼這個繩子和這個牆所能圍成的最大面積就是那個人的全部。如果把人比作一根長度為n的繩子,那麼這根繩子和牆所能圍成的最大面積是多少呢?
輸入:
共T組測試用例(T<=100)
每行一個正整數N(N<=100)
輸出:
對於每組樣例
如果能夠圍出來,則輸出一個數,代表繩子和牆所能圍成的最大面積;
如果不可能圍出來,輸出"Impossble"(沒有引號)
答案保留八位小數
sample:
input:
2
1
99
output:
0.15915494
1559.87759724
Hint:
pi=acos(-1)

#include <stdio.h>
#include <math.h>
int main()
{
    int t,n;
    double area;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        if(n == 0)
        printf("Impossble");
        else
        {
            area = (n * n) / (2 * acos(-1));
            printf("%.8lf",area);
        }
    }
}

就是簡單的數學呀,周長相同時,什麼形狀面積最大,那當然是圓形咯!但是因為這裡有一堵牆,所以牆是直徑,繩子只能圍半圓,於是n就是半圓的周長,最大的area自然出來了。(點名批評廣工的英語水平,impossible都拼錯,幸好我是複製黨!!)

第十二題 最小公約數和雜湊表

題目:如果[a,b]表示a和b的最小公倍數,那麼[a,b]/a能得到多少個不同的數字呢?限制條件:a的範圍是1到1000。
輸入:
第一行輸入一個整數T(T<=50),代表有T組樣例。
對於每組樣例:
輸入一個數b(1<=b<=100000)
輸出:
對於每個b,輸出一個整數,表示[a,b]/a可以得到多少個不同的數。
sample:
input:
1
4
output:
3

#include <stdio.h>
#include <string.h>
int gcd (int m,int n)
{
    return n?gcd(n,m%n):m;
}
int a[1005];

int main()
{
    int t,b,count,i,k;
    scanf("%d",&t);
    while(t--)
    {
        memset(a,0,sizeof(a));
        scanf("%d",&b);
        count = 0;
        for(i=1; i<=1000; i++)
        {
            a[gcd(i,b)]++;
        }
        for(i=1; i<=1005; i++)
        {
            if(a[i] != 0)
            {
                count++;
            }
        }
        printf("%d\n",count);
    }
}

一開始很傻,以為真的是要求a和b的最小公倍數除以a,然後再統計不同數字,後來想了想,數字範圍太tm大了呀,沒法做呀,後來列了一下式子,發現很多東西都約掉了,只剩下b/gcd(a,b),那問題變得簡單了呀,就求gcd(a,b),然後把那些數字弄成雜湊表就完事了啊,棒!不愧是我!

第十三題 水題

題目:如同角谷猜想,對任意的正整數,若為偶數,則把它除以2,若為奇數,則把它乘以3加1。經過如此有限次運算後,總可以得到正整數值1。世界線的收束也是如此
輸入:
第一行讀入一個T(T<=50),表示有T組樣例
接下來T行,每行一個整數n (2<=n<=200)
輸出:
對於每一組樣例,輸出他的運算過程
兩個樣例之間用空行分割
sample:
input:
1
3
33+1=10
10/2=5
5
3+1=16
16/2=8
8/2=4
4/2=2
2/2=1

#include <cstdio>
using namespace std;
void trick (int n)
{
    while(n != 1)
    {
        if(n%2 == 0)
        {
            printf("%d/2=%d\n",n,n/2);
            n = n / 2;
        }
        else
        {
            printf("%d*3+1=%d\n",n,n*3+1);
            n = n * 3 + 1;
        }
    }
}

int main()
{
    int n,i,t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        trick(n);
        if(t != 0)
        printf("\n");
    }
}

emmm…沒什麼好說的,我們接著a下一題吧!

第四題 基礎不牢打什麼acm.jpg

題目:
眾所周知…在常用的基本變數型別有6種,對於每一種基本變數型別中:
int佔用4個位元組;
bool佔用1個位元組,
long long佔用8個位元組,
double佔用8個位元組,
char佔用1個位元組,
float佔用4個位元組。
輸入:
第一行一個整數T,代表有T組樣例。
對於每組樣例:
第一行n標識輸入有n行 (n<=100000)
接下來n行如上述所示。
輸入保證:
1:每一行只有一個標識
2:輸入的基本格式為:
<變數型別> <變數名>;
3:一行只有一個型別
4:變數名的長度不超過10,且對於每組樣例,輸入的n個變數名均不同
例如
存在:int a;
而不存在:int a,b;
5:n的和不超過200000
輸出:
輸出用了多少KB(千位元組)記憶體(向上取整)
sample:
input:
1
1
int a;
output:
1

#include <stdio.h>
#include <math.h>
int main()
{
    char a[15],ch;
    int t,n,i,sum,ans;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        getchar();
        sum = 0;
        while(n--)
        {
            gets(a);
            ch = a[0];
            if(ch == 'i')
            sum += 4;
           if(ch == 'b')
            sum += 1;
           if(ch == 'l')
            sum += 8;
           if(ch == 'd')
            sum += 8;
           if(ch == 'c')
            sum += 1;
           if(ch == 'f')
            sum += 4;
        }
        ans = ceil(sum * 1.0 / 1024);
        printf("%d\n",ans);
    }
}

第一眼,這題不難,能做,每種資料型別開頭的首字母都不一樣,就用字串的首字母來判斷就好了呀,然後ceil是向上取整函式,信心滿滿寫下程式碼,我敲!!怎麼我字串還沒輸入就出結果了呢?!換了n種輸入方式還是無果,最後傅老大告訴我,連續輸入的時候,如果gets前一個是回車的話,gets就吃掉了回車,然後就會以為你已經輸入完了,所以在gets前面加個getchar()作為緩衝就好了,然後感慨自己基礎真的不牢固啊…

好,然後這兩天再慢慢啃那些沒思路的題吧…