1. 程式人生 > >NYSIT第四次周賽題解

NYSIT第四次周賽題解

NYIST–2018大一新生第四次周賽

連結:https://cn.vjudge.net/contest/269128 密碼:nyist

A - 穆穆清風至 HDU - 2550

畫圖,模擬一下即可

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct Node{
int len,num;
}node[110];
void Print(int len)//輸出一行長度為len 的弓箭
{
    printf(">+");
    for(int i=0;i<len-2;++i)
        printf("-");
    printf("+>\n");
}
bool cmp(Node a,Node b)//將短的放前面
{
    return a.len<b.len;
}
int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=0;i<n;++i)
            scanf("%d %d",&node[i].len,&node[i].num);
        sort(node,node+n,cmp);
        for(int i=0;i<n;++i)
        {
            for(int j=0;j<node[i].num;++j)//每一種箭 輸出num個
                Print(node[i].len);
            printf("\n");
        }
    }
    return 0;
}


B - 無法提交 CodeForces - 702A

求最大連續嚴格遞增長度

思路:記錄當前嚴格遞增長度和上一個數,每輸入一個數判斷是否與前面那個數構成嚴格遞增關係,更新變數即可。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define maxn 110
using namespace std;
int main()
{
    int maxlen,n,val,lastval;
    while(~scanf("%d",&n))
    {
        lastval=-1;//上一個數
        maxlen=-1;//最長的連續遞增長度
        int cnt=0;//現在當前有多少個連續的嚴格遞增數
        /*
        每次在輸入數時變數代表的意義
        val:現在輸入的數
        lastval:上一個數(初始值為-1)
        cnt:現在當前有多少個連續的嚴格遞增數
        maxlen:最大的cnt
        */
        while(n--)
        {
            scanf("%d",&val);
            if(val>lastval)//還保持嚴格遞增
                cnt++;
            else//不能保持嚴格遞增  
            {
                if(maxlen<cnt)//更新
                    maxlen=cnt;
                cnt=1;
            }
            lastval=val;
        }
        if(maxlen<cnt)
            maxlen=cnt;
        printf("%d\n",maxlen);
    }
}

C - 吹我羅衣裾 HDU - 2003

題目都說了用double ,float的精度較低

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define maxn 1100
using namespace std;
int main()
{
    double k;
    while(~scanf("%lf",&k))
    {
        if(k<0.0)
            k=-1.0*k;
        printf("%.2lf\n",k);
    }
}

D - 青袍似春草 HDU - 1420

快速冪模板,注意A,B,C<=1000000,A*A的過程可能會爆int(1e9),所以用需要用long long

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define maxn 1100
using namespace std;
typedef long long ll;
ll quick_pow(ll a,ll b,ll mod)//快速冪板子,可以記下來
{
    ll ans=1;
    while(b)
    {
        if(b&1)
            ans=(ans*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return ans;
}
int main()
{
    ll a,b,mod,ans;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lld %lld %lld",&a,&b,&mod);
        printf("%lld\n",quick_pow(a,b,mod));
    }
}

E - 無法提交 CodeForces - 977A

k的值較小,模擬一下過程即可

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define maxn 110
using namespace std;
int main()
{
    int n,k;
    scanf("%d %d",&n,&k);
    while(k)
    {
        if(n%10)
            n--;
        else
            n/=10;
        --k;
    }
    printf("%d\n",n);
}

F - 無法提交 CodeForces - 510A

簡單畫圖題,模擬過程即可

/*
輸出第k行:
k為奇數:       輸出m個'#' (#####)
k為4的倍數:    輸出一個'#'   m-1個'.'     (#..)
k是2的倍數但是不是4的倍數:輸出 m-1個'.' 一個'#' (..#)
輸出n行即可
*/
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define maxn 110
using namespace std;
int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=1; i<=n; ++i)
    {
        if(i&1)//i為奇數
            for(int j=1; j<=m; ++j)
                printf("#");
        else
        {
            if(i%4==0)//i是4的倍數 輸出#..
            {
                printf("#");
                for(int j=1; j<=m-1; ++j)
                    printf(".");
            }
            else
            {
                for(int j=1; j<=m-1; ++j)
                    printf(".");
                printf("#");
            }
        }
        printf("\n");
    }
}

G - 無法提交 CodeForces - 501A

我相信你讀完這道題就能A

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define maxn 110
using namespace std;
int main()
{
    int a,b,c,d;
    int score1,score2;
    while(~scanf("%d %d %d %d",&a,&b,&c,&d))
    {
        score1=max(3*a/10,a-(a/250)*c);
        score2=max(3*b/10,b-(b/250)*d);
        if(score1==score2)
            printf("Tie\n");
        else
            printf("%s\n",score1>score2?"Misha":"Vasya");
    }
}

H - 安得抱柱信 HihoCoder - 1768

​ 找規律題吧,我做這道題暴力了一遍,發現在5位數以內滿足條件的只有2,3,5,7,23,37,53,73,373這9個數,所以就猜應該只有這9個數。因為一個5位數可以看作左邊是一個1位數,右邊是一個4位數,因為四位數中沒有“真素數”所以五位數一定不會是一個“真素數”(因為“真素數“滿足其左邊和右邊都是”真素數“)。然後擴充套件一下,得到超過5位數的數的都不會是“真素數”,所以”真素數“就只有這9個數了

AC程式碼:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define maxn 1100000
using namespace std;
typedef long long ll;
int ans[]={2,3,5,7,23,37,53,73,373};
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        if(n<=9)
            printf("%d\n",ans[n-1]);
        else
            printf("-1\n");
    }

}

暴力過程的程式碼:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define maxn 1100000
using namespace std;
typedef long long ll;
int prime[maxn];
int Solve(int k)//判斷k是不是真正的素數
{
    int wis[10];
    int len=0;
    while(k)
    {
        wis[len++]=k%10;
        k/=10;
    }//注意陣列中的數存的順序是從低位到高位的
    for(int i=len-1;i>=0;--i)
    {
        for(int j=i;j>=0;--j)//取i  j之間的數字(包括i j下標)
        {
            int val=0;
            for(int k=i;k>=j;--k)//求 i  j之間的數字為多少
            {
                val*=10;
                val+=wis[k];
            }
            if(prime[val])
                return 0;
        }
    }
    return 1;
}
int main()
{
    prime[0]=prime[1]=1;//非素數用 1表示
    for(int i=2;i<=1000;++i)
    {
        if(!prime[i])
        {
            for(int j=i*i;j<=1000000;j+=i)
                prime[j]=1;
        }
    }
    for(int i=1;i<=1000000;++i)
    {
        if(Solve(i))
            printf("%d\n",i);
    }
}

I - 皎日以為期 HihoCoder - 1051

思路:

貪心問題,m次補籤卡,求最長連續登陸天數,

補籤卡夠直接輸出100.

如果不能全補籤,就列舉m個補籤卡的位置(一定是連續的)。


#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define maxn 110
using namespace std;
int day[maxn];
int main()
{
    int t,n,m;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&n,&m);
        day[0]=0;
        for(int i=1;i<=n;++i)
        {
            scanf("%d",day+i);
        }
        if(m>=n)//可以全部補籤
        {
            printf("100\n");
            continue;
        }
        int ans=-1;
        for(int i=0;i<=n-m;++i)//列舉範圍即可
        {
            if(day[m+i+1]-day[i]-1>ans)//第i 和第m+i+1之間的補籤 得到連續的天數=day[m+i+1]-day[i]-1
                ans=day[m+i+1]-day[i]-1;
        }
        printf("%d\n",ans);
    }
}

J - 新加題1 HihoCoder - 1712

思路:

"一般我們在對字串排序時,都會按照字典序排序。當字串只包含小寫字母時,相當於按字母表"abcdefghijklmnopqrstuvwxyz"的順序排序。現在我們打亂字母表的順序,得到一個26個字母的新順序。例如"bdceafghijklmnopqrstuvwxyz"代表’b’排在’d’前,'d’在’c’前,'c’在’e’前…… "

將給出的26個小寫字母依此當成a~z即可,進行排序即可,因為要輸出字串,所以需要記下未轉化前的字串

給定一個結構體:裡面有兩個元素s1 s2都為char陣列,s1為輸入字串,s2為轉化後的字串,然後結構體排序即可。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define maxn 110
using namespace std;
struct Node{
    char s1[maxn],s2[maxn];
}node[1100];
int bm[30];
bool cmp(Node a,Node b)
{
   int val=strcmp(a.s2,b.s2);
   return val<0;//代表排序過後 字串小的在前面
}
int main()
{
    int n;
    scanf("%d",&n);
    char ss[30];
    scanf("%s",ss);
    for(int i=0;i<26;++i)
        bm[ss[i]-'a']=i;//bm[k]的意思k+'a'對應的字元為bm[k]+‘a’
    for(int i=0;i<n;++i)
    {
        scanf("%s",node[i].s1);
        int len=strlen(node[i].s1);
        for(int j=0;j<len;++j)
            node[i].s2[j]=bm[node[i].s1[j]-'a']+'a';
        node[i].s2[len]='\0';
    }
    sort(node,node+n,cmp);//排序
    for(int i=0;i<n;++i)
    {
        printf("%s\n",node[i].s1);
    }
}

K - 新加題2 HihoCoder - 1562

思路:

根據當前時間和過的秒數,計算出最後的時間,根據最後時間小時 分鐘 計算出時針的角度分針角度 即可

程式碼:

/*
K - 新加題2
*/
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define maxn 110

/*
1.計算最後的 h m s
2.計算此時的時針與分針夾角
因為夾角只與最後針的位置與關,所以保證h m s在一定範圍內,用公式求出夾角即可
時針: 1h 轉60° 1min轉0.5°   1s轉 (0.5/60)°
分針: 60min轉360  1min轉 6°  1s轉0.1°
*/
using namespace std;
int main()
{
    int bh,bm,bs;//開始時鐘的時刻
    int hh,mm,ss;//最後時鐘的時刻
    int t,T;
    float mines_angle,hour_angle;
    float ans;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d %d %d",&bh,&bm,&bs);
        scanf("%d",&t);
        ss=bs+t%60;
        t/=60;
        mm=bm+t%60;
        t/=60;
        hh=bh+t;
        mm+=ss/60;
        ss=ss%60;//保證秒針的值在0~59
        hh+=mm/60;
        mm=mm%60;//保證分針的值在0~59即可
        hh%=12;//保證時針在0~11之內
        mines_angle=(float)mm*6.0+(float)ss*0.1;
        hour_angle=(float)hh*30.0+(float)mm*0.5+(float)ss*(0.5/60.0);
        ans=hour_angle-mines_angle;
        if(ans<0.0)
            ans*=-1.0;
        if(ans>180.0)
            ans=360.0-ans;
        printf("%.4f\n",ans);
    }
}