NOIP 提高组 初赛 四、阅读程序写结果 习题集(八)NOIP2012-NOIP2013

来源:互联网 发布:visual attention知乎 编辑:程序博客网 时间:2024/05/29 18:19

NOIP 提高组 初赛 四、阅读程序写结果 习题集(八)NOIP2012-NOIP2013

1.第十八届(NOIP2012)

问题:

1.

//2012.4.1
#include <stdio.h>
int main(){
    int n,i,temp,sum;
    int a[100];
    scanf("%d",&n);
    for(i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(i=1;i<=n-1;i++)
        if(a[i]>a[i+1]){
            temp=a[i];
            a[i]=a[i+1];
            a[i+1]=temp;
        }
    for(i=n;i>=2;i--)
        if(a[i]<a[i-1]){
            temp=a[i];
            a[i]=a[i-1];
            a[i-1]=temp;
        }
    sum=0;
    for(i=2;i<=n-1;i++)
        sum+=a[i];
    printf("%d\n",sum/(n-2));
    return 0;
}
//输入:8
//40 70 50 70 20 40 10 30
 

2.

//2012.4.2
#include <stdio.h>
int gcd(int a,int b){
    if(a%b==0)
        return b;//网上流传的pascal有些此处return 0; 
    else
        return gcd(b,a%b);
}
int main(){
    int n,i,ans;
    scanf("%d",&n);
    ans=0;
    for(i=1;i<=n;i++)
        if(gcd(n,i)==i)
            ans++;
    printf("%d\n",ans);
    return 0;
}
//输入:120
 

3.

//2012.4.3
#include <stdio.h>
const int size=20;
int data[20];
int n,i,h,ans;
void merge(){
    data[h-1]+=data[h];
    h--;
    ans++;
}
int main(){
    scanf("%d",&n);
    h=1;
    data[h]=1;
    ans=0;
    for(i=2;i<=n;i++){
        h++;
        data[h]=1;
        while(h>1&&data[h]==data[h-1])
            merge();
    }
    printf("%d\n",ans);
    return 0;
}
//(1)
//输入:8
//(2)
//输入:2012
 

4.

//2012.4.4
#include <stdio.h>
#include <string.h>
int left[20],right[20],father[20];
char s1[20],s2[20],s3[20];
int n,ans,tmpLen;
void check(int x){//本题pascal写法与C差异较大,且有些错误 
    if(left[x]>=0)
        check(left[x]);
    tmpLen=strlen(s3);
    s3[tmpLen]=s1[x];
    s3[tmpLen+1]='\0';
    if(right[x]>=0)
        check(right[x]);
}
void calc(int x,int dep){
    ans=ans+dep*(s1[x]-'A'+1);
    if(left[x]>=0)
        calc(left[x],dep+1);
    if(right[x]>=0)
        calc(right[x],dep+1);
}
void dfs(int x,int th){
    if(th==n){
        s3[0]='\0';
        check(0);
        if(strcmp(s2,s3)==0){
            ans=0;
            calc(0,1);
            printf("%d\n",ans);
        }
        return;
    }
    if(left[x]==-1&&right[x]==-1){
        left[x]=th;
        father[th]=x;
        dfs(th,th+1);
        father[th]=-1;
        left[x]=-1;
    }
    if(right[x]==-1){
        right[x]=th;
        father[th]=x;
        dfs(th,th+1);
        father[th]=-1;
        right[x]=-1;
    }
    if(father[x]>=0)
        dfs(father[x],th);
}
int main(){
    scanf("%s",s1);
    scanf("%s",s2);
    n=strlen(s1);
    memset(left,-1,sizeof(left));
    memset(right,-1,sizeof(right));
    memset(father,-1,sizeof(father));
    dfs(0,1);
    return 0;
}
//输入:ABCDEF
//BCAEDF
 

问题解答:

1.就算不熟悉冒泡排序,此题也挺简单,直接模拟,过程如下:


看起来数据量挺大,但写起来挺快,最多5分钟,肯定好了,

答案:41

1简单

2.作了模拟,如图所示:


发现该程序意图是统计n与i能整除的数量。

能被120整除的数:1,2,3,4,5,6,8,10,12,15,20,24,30,40,60,120共计16个。

答案:16

该题一不小心,就容易漏数。

2中等

想到一个好办法:

120/1=120,120/2=60,120/3=40,120/4=30,120/5=24,120/6=20,120/8=15,120/10=12.

此种办法,一个不漏,

1,120,2,60,3,40,4,30,5,24,6,20,8,15,10,12.一共16个。

2简单

3.输入8思考过程如下:


答案:7

难度中等,能将输入8做对,水平已经不错,证明具有相当的跟踪程序的水平。此题难在while()而不是if()。

输入2012

参考:https://zhidao.baidu.com/question/580345391.html

n值 数组有效元素(包括转换前和转换后)
i=2 1,1->2
i=3 2,1
i=4 2,1,1->2,2->4
i=5 4,1
i=6 4,1,1->4,2
i=7 4,2,1
i=8 4,2,1,1->4,2,2->4,4->8
至此次转换次数(->)为7次,即ans=7
i=9 8,1
i=10 8,1,1->8,2
i=11 8,2,1
i=12 8,2,1,1->8,2,2->8,4
i=13 8,4,1
i=14 8,4,1,1->8,4,2
i=15 8,4,2,1
i=16 8,4,2,1,1->8,4,2,2->8,4,4->8,8->16

由上可知,数组有效元素的和为n,当n可以表示为2(x)时,转换次数为2(0)+2(1)+2(2)+2(3)+...+2(x-1)
当i从1变到1024时,转换次数为2(0)+...+2(9)=1023
当i从1变到2048时,转换次数为2(0)+...+2(10)=2047,但是i变不到2048,只变到2012(n的值)
所以,最终数组的有效元素是:
i=2012 1024,512,256,128,64,16,8,4 //有效数组元素的和为2012(此处不清楚,还需消化
所以,当n=2012时,最终的结果是:
t(1024)+t(512)+t(256)+t(128)+t(64)+t(16)+t(8)+t(4) //t(x)表示从数组初始状态变到x状态
=1023+511+255+127+63+15+7+3=2004

答案:2004

此处难度:难 考试中先跳过。

4.程序跟得晕乎乎的,暂时搁置,等实力强劲时再来。

答案:55


1.第十九届(NOIP2013)

问题:

1.

//2013.4.1
#include <stdio.h>
#include <string.h>
const int SIZE=100;
int main(){
    int i,n;
    char str[SIZE];
    int isPlalindrome;
    scanf("%s",str);
    n=strlen(str);
    isPlalindrome=1;
    for(i=0;i<n/2;i++){
        if(str[i]!=str[n-i-1]) 
            isPlalindrome=0;
    }
    if(isPlalindrome)
        printf("Yes\n");
    else
        printf("No\n");
}
//输入:abceecba
 

2.

//2013.4.2
#include <stdio.h>
int main(){
    int a,b,u,v,i,num;
    scanf("%d%d%d%d",&a,&b,&u,&v);
    num=0;
    for(i=a;i<=b;i++){
        if(i%u==0||i%v==0)
            num++;
    }
    printf("%d\n",num);
    return 0;
}
//输入:1 1000 10 15
 

3.

//2013.4.3
#include <stdio.h>
const int SIZE=100;
int main(){
    int n,ans,i,j;
    int height[SIZE],num[SIZE];
    scanf("%d",&n);
    for(i=0;i<n;i++){
        scanf("%d",&height[i]);
        num[i]=1;
        for(j=0;j<i;j++)
            if(height[j]<height[i]&&num[j]>=num[i])
                num[i]=num[j]+1;
    }
    ans=0;
    for(i=0;i<n;i++)
        if(num[i]>ans)
            ans=num[i];
    printf("%d\n",ans);
    return 0;
}
//输入:8
// 3 2 5 11 12 7 4 10


4.

//2013.4.4
#include <stdio.h>
#include <string.h>
const int SIZE=100;
int n,m,p,count;
int a[SIZE][SIZE];
void colour(int x,int y){
    count++;
    a[x][y]=1;
    if(x>1&&a[x-1][y]==0)
        colour(x-1,y);
    if(y>1&&a[x][y-1]==0)
        colour(x,y-1);
    if(x<n&&a[x+1][y]==0)
        colour(x+1,y);
    if(y<m&&a[x][y+1]==0)
        colour(x,y+1);
}
int main(){
    int ans,x,y,i,j;
    memset(a,0,sizeof(a));
    scanf("%d%d%d",&n,&m,&p);
    for(i=1;i<=p;i++){
        scanf("%d%d",&x,&y);
        a[x][y]=1;
    }
    ans=0;
    for(i=1;i<=n;i++)
        for(j=1;j<=m;j++)
            if(a[i][j]==0){
                count=0;
                colour(i,j);
                if(ans<count)
                    ans=count;
            }
    printf("%d\n",ans);
    return 0;
}
//输入:
/*
6    5  9
1    4
2    3
2    4
3    2
4    1
4    3
4    5
5    4
6    4
*/


问题解答:

1.思考过程如图所示:


直接跟踪程序,此题两三分钟即可做好。

答案:Yes

1简单

2.思考过程如图所示:


答案:133

耗时:两三分钟

3.思考过程如图所思:


num[i]>ans这段代码是在num中找最大的数。

很快能得出答案:4

耗时:5分钟

3中等


4.思考过程如图所示:

跟踪程序,发现colour函数核心处理部分,如图所示:


很快发现该函数是统计同一区域0的个数。

该程序意图明了:统计同一区域0的个数,找出最多0的个数。

答案:7

耗时:5分钟

4中等

2016-12-31 12:04


阅读全文
0 0
原创粉丝点击