ACM2016級新生第三週訓練賽

本次是弱校題解-比賽鏈接

備用鏈接

題目還是比較基礎,比較簡單。認真補題,學會學習。





A -人見人愛A^B

題解: 求 A的B次方,我們可以用循環進行累乘操作,進而計算出次方.因爲題目要求只需要求出最後三位,所以每次對 1000 求餘數,最後輸出即可。

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


int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0&&m==0) return 0;
        int ans=1,i;
        for(i=1;i<=m;i++)
        {
            ans=ans*n;
            ans%=1000;
        }
        printf("%d\n",ans);
    }
    return 0;
}

B -數列有序!

題解:詳見代碼,輸出的時候判斷 大於等於前一個數且小於等於後一個數,滿足之後輸出,輸出之後不要重複輸出,所以用了一個標記變量標記這個數字是否已經輸出。



#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#define INF 2e9

int a[105];
int ans[105];

int main()
{
   // printf("%d\n",INF);
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0&&m==0) return 0;
        int i,flag=1;
        a[0]=-INF;
        a[n+1]=INF;
        for(i=1; i<=n; i++)
            scanf("%d",&a[i]);
            int k=1;
        for(i=1;i<=n+1;i++)
        {
            if(m>=a[i-1]&&m<=a[i]&&flag)
            {
                ans[k++]=m;
                flag=0;
            }
            ans[k++]=a[i];
        }
        for(i=1;i<k-1;i++)
        {
           if(i==k-2)  printf("%d\n",ans[i]);
           else printf("%d ",ans[i]);
        }
    }
    return 0;
}



C -密碼

思路:首先判斷長度是否合格,不合格輸出 NO ,合格再進行下一步的判斷。判斷字符種類是否大於等於3種。我的方法是用4個變量標記一下是否存在?到最後判斷一下。思路就醬紫。具體實現看看代碼吧。


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define MAXSIZE 100000+10


char str[MAXSIZE];
int main()
{
    int ncase;
    scanf("%d",&ncase);
    while(ncase--)
    {
        scanf("%s",str);
        int len=strlen(str);
        int f1=0,f2=0,f3=0,f4=0;
        if(len>=8&&len<=16)
        {
            int i;
            for(i=0;i<len;i++)
            {
                if(str[i]>='A'&&str[i]<='Z') f1=1;
                if(str[i]>='a'&&str[i]<='z') f2=1;
                if(str[i]>='0'&&str[i]<='9') f3=1;
                if(str[i]=='~'||str[i]=='!'||str[i]=='@'||str[i]=='#'||str[i]=='$'||str[i]=='%'||str[i]=='^') f4=1;
            }
            if(f1+f2+f3+f4>=3) printf("YES\n");
            else printf("NO\n");
        }
        else printf("NO\n");
    }
    return 0;
}

D -驗證角谷猜想

思路:按照題目意思模擬一遍,符合要求的數字存在一個數組裏面,最後判斷數組中的個數是否是0?不是零就輸出,注意是兩個數之間有一個空格,行末尾是沒有空格的。注意這個就好了。


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define MAXSIZE 100000+10

int a[MAXSIZE];
int main()
{
    int ncase;
    scanf("%d",&ncase);
    while(ncase--)
    {
        int n,k=0;
        scanf("%d",&n);
        while(1)
        {
            if(n==1) break;
            if(n%2==1)
            {
                a[k++]=n;
                n=n*3+1;
            }
            else
            {
                n/=2;
            }
        }
        if(k==0) printf("No number can be output !\n");
        else
        {
            int i;
            for(i=0;i<k;i++)
            {
                if(i==k-1) printf("%d\n",a[i]);
                else printf("%d ",a[i]);
            }
        }

    }
    return 0;
}

E -尋找素數對

思路:第一步篩法打素數表,因爲需要找距離最近的素數對,所以枚舉(用循環)所有相鄰的兩個素數。

 

#include <stdio.h>
#include <string.h>
int main()
{
    int a[10005],i,j;
    memset(a,0,sizeof(a));// 0 代表是素數
    a[0]=a[1]=1;
    for (i = 2 ; i <= 10000 ; i++)  //篩法打素數表
    {
        if ( a[i] == 0)
        {
            for ( j = i + i ; j  < 10005 ; j += i)
                a[j] = 1;
        }
    }
    int m,n;
    while(scanf("%d",&m)!=EOF)
    {
        n = m/2;
        for ( i = n; i > 5; i--)
        {
            if ((a[i] == 0 && a[m-i] == 0))
            {
                printf("%d %d\n",i,m-i);
                break;
            }
        }
    }
    return 0;
}

F - 求數列的和

思路:直接模擬,循環

#include<stdio.h>
#include<math.h>
int main()
{
	int i;
	double n,m,sum;
	while(scanf("%lf %lf",&n,&m)!=EOF)
	{
		sum=0;
		for(i=0;i<m;i++)
		{
			sum+=n;
			n=sqrt(n);
		}
		printf("%.2lf\n",sum);
	}
	return 0;
}

G -做減法

分析:知道題目就是算a-b,只是輸出的時候,每三個數字之間用一個英文狀態下的逗號隔開。

思路:先算出a-b的值,然後把這個數字的各個位存在一個數組裏面,然後對於數組下標能被 3 整除的數的後面加上一個逗號就可以了。注意0也能夠被3整除,但是最後一個是不需要逗號的。還有值得注意 的是如果這個數字爲0需要特殊判斷一下。綜上所述,代碼見下面。


#include<stdio.h>

int main()
{
    int a,b;
    while(scanf("%d%d",&a,&b)!=EOF)
    {
        int ans=a-b,k=0,i;
        if(ans<0) printf("-"),ans=-ans;
        int num[40];
        if(ans==0) printf("0");
        else
        {
            while(ans)
            {
                num[k++]=ans%10;
                ans/=10;
            }
            for(i=k-1; i>=0; i--)
            {
                printf("%d",num[i]);
                if(i%3==0&&i>0) printf(",");
            }
        }
        printf("\n");
    }
    return 0;
}

H -A hard Aoshu Problem

思路: 本題解法多樣我寫一個就夠了。用一個數組來統計某一個數字出現的次數。因爲數字是從 -100開始的,所以我在標記的時候這個數字加100 作爲標記數組的下標。最後從前往後找出一個最大值,因爲題目要求值要儘量小,所以我們更新最大值的時候,只有在後面的數字大於前面的才進行更新,相等的時候也不更新最大值。


所以詳見代碼:

#include<stdio.h>
#include<string.h>
int a[250];
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        memset(a,0,sizeof(a));
        int i;
        for(i=0;i<n;i++)
        {
            int num;
            scanf("%d",&num);
            a[num+100]++;
        }
        int maxn=-1,pos=0;
        for(i=0;i<=200;i++)
        {
            if(a[i]>maxn) maxn=a[i],pos=i;
        }
        printf("%d %d\n",pos-100,maxn);
    }
    return 0;
}

I -18歲生日

思路: 如果是在2月29出生的一定沒有18歲的生日,因爲18不能夠被4整除。所以XXX;那麼不是2月29的應該如何計算?我們假設每年都有365天,那麼總共會有  365*18  這麼多天,因爲有閏年所以判斷會經過多少個閏年的2月。如果出生在3月及以後那麼就不會經過當年的2月,所以當出生月份 >= 3 ,那麼就從下一年開始計算。最後兩者相加即爲最終答案。

#include <stdio.h>
int main()
{
    int n,i,y,m,d,sum;
    scanf("%d",&n);
    while(n--)
    {
        sum=0;
        scanf("%d-%d-%d",&y,&m,&d);
        if(m==2&&d==29)
        {
            printf("-1\n");
            continue;
        }
        if(m>=3) y++;
        for(i=y; i<y+18; i++)
            if(i%4==0&&i%100!=0||i%400==0)
                sum++;
        printf("%d\n",365*18+sum);
    }
    return 0;
}

I -18歲生日    

作者:LZQ

大致思路:
可知n可分爲兩種:
1.n==1,只輸出輸出中心花色字符
2.n!=1時

觀察可知,共有n排,n列,
且第一排和最後一排均是空格,n-2箇中心花色字符或外筐花色字符,空格;
當(n-1)%2==0時是中心花色字符,當(n-1)%2==1時是外筐花色字符;

其他排即第i排從第一個字符到第i個字符外筐花色字符和中心花色字符交替,
第i+1個字符到第n-i個字符均爲外筐花色字符或中心花色字符,
第n-i+1到第n個字符依然是外筐花色字符和中心花色字符交替。
且整個圖案關於第n/2+1排對稱,可用取餘來交換輸出這些字符。

由此規律可寫出代碼

#include<stdio.h>
int main()
{
    int n,flag=0;
    char c1,c2,temp;
    while(scanf("%d %c %c",&n,&c1,&c2)!=EOF)
    {
        if(flag)      //題目要求每兩組數據間要有一個換行,即除了以一組數據外,其他數據輸出前都有一個換行
            printf("\n");
        int i,j,k;
        if(n==1)//特判n==1的情況
            printf("%c\n",c1);  
        if((n-1)/2%2==0)
            temp=c1,c1=c2,c2=temp;  //觀察可知若(n-1)/2爲偶數,則第一排和最後一排均爲c2,否則第一排和最後一排均爲c1
        if(n!=1)    //若n不爲1
            for(i=1; i<=n; i++)
            {
                k=i;
                if(i>n/2+1) k=n-i+1; 
                if(i==1||i==n)
                {
                    printf(" ");
                    for(j=1; j<=n-2; j++)
                        printf("%c",c2);
                    printf(" ");
                }
                else
                    for(j=1; j<=n; j++)
                    {
                        if(j>k&&j<=n-k)
                        {
                            if(k&1)
                                printf("%c",c2);
                            else
                                printf("%c",c1);
                        }
                        else
                        {
                            if(j&1)
                                printf("%c",c2);
                            else
                                printf("%c",c1);
                        }
                    }
                printf("\n");
            }
        flag=1;
    }
}



注:賽後需認真補題,不然題目就浪費了。


發佈了100 篇原創文章 · 獲贊 46 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章