NOIP 提高組 初賽 四、閱讀程序寫結果 習題集(三)NOIP2002-NOIP2003
1.第八屆(NOIP2002)
問題(原文是pascal,按題意,本人改寫成C,C++版本):
1.
//2002.3.1
#include <stdio.h>
#include <string.h>
int main(){
int i,n,jr,jw,jb;
char ch1;
char ch[22];
scanf("%d",&n);
scanf("%s",ch);
jr=0;
jw=n-1;
jb=n-1;
while(jr<=jw){
if(ch[jw]=='R'){
ch1=ch[jr];
ch[jr]=ch[jw];
ch[jw]=ch1;
jr++;
}else if(ch[jw]=='W'){
jw--;
}else{
ch1=ch[jw];
ch[jw]=ch[jb];
ch[jb]=ch1;
jw--;
jb--;
}
}
printf("%s\n",ch);
return 0;
}
//輸入:
//10
//RBRBWWRBBR
2.
//2002.3.2
//將pascal轉換成C、C++過程中,還出現了些小紕漏,不過讀pascal代碼能力更進步了.
#include <stdio.h>
int main(){
int i,j,s,sp1;
int p;
int a[11];
sp1=1;
a[1]=2;
j=2;
while(sp1<10){
j++;
p=1;
for(i=2;i<=j-1;i++)
if(j%i==0)
p=0;
if(p){//開始將該段if放在for循環中,答案不對,後將該段if移出for循環,答案正確
sp1++;
a[sp1]=j;
}
}
j=2;
p=1;
while(p){
s=1;
for(i=1;i<=j;i++)
s*=a[i];
s++;
for(i=2;i<=s-1;i++)
if(s%i==0)
p=0;
j++;
}
printf("%d\n",s);
return 0;
}
3.
//2002.3.3
#include <stdio.h>
#include <math.h>
int main(){
float d1,d2,x,min;
min=10000;
x=3;
while(x<15){
d1=sqrt(9+(x-3)*(x-3));
d2=sqrt(36+(15-x)*(15-x));
if((d1+d2)<min)
min=d1+d2;
x+=0.001;
}
printf("%8.2f\n",min);
return 0;
}
問題解答:
1.字符串問題,總體比較簡單,信心足,根據輸入數據,跟蹤程序,記錄相關數據信息:
答案:RRRRWWBBBB
1中等
2.跟着程序跑一段,很快發現數組a是存儲質數的。
a[1]=2
a[2]=3
a[3]=5
a[4]=7
a[5]=11
a[6]=13
a[7]=17
a[8]=19
a[9]=23
a[10]=29
第二個while循環是判斷s值是否是質數,非質數,跳出循環,打印s值。
s=7
s=31
s=211
s=2311
s=30031
本人就沒往下算了,倒在黎明前啊。
不過30031非質數也是難判斷,編了程序才發現30031=59*509,考試中算不出啊,
答案:30031
2難,難在判斷非質數。
3.自個弄了半天,沒對上答案,具體分析也就不說了,參考http://www.docin.com/p-270931446.html
做個糾正,交點x=7.000。
過程如下:
d1=sqrt(9+(x-3)*(x-3))=sqrt((0-3)*(0-3)+(x-3)*(x-3))
d1表示(x,0)與(3,3)兩點間距離
d2=sqrt(36+(15-x)*(15-x))=sqrt((0-6)*(0-6)+(x-15)*(x-15))
d2表示(x,0)與(15,6)兩點間距離
思考過程如圖所示(兩點之間最短距離是直線):
min=(15-3)^2+(6-(-3))^2=15.00
答案:15.00
3難
1中等2難3難
2.第九屆(NOIP2003)
問題(原文是pascal,按題意,本人改寫成C,C++版本):
1.
//2003.4.1
#include <stdio.h>
int main(){
long long a,b,c,d,sum;
int a1,b1,c1,d1;
scanf("%d%d%d%d",&a1,&b1,&c1,&d1);
a=a1;
b=b1;
c=c1;
d=d1;
a%=23;
b%=28;
c%=33;
sum=a*5544+b*14421+c*1288-d;//摘抄文件是1228,後搜索網絡發現是1288
sum+=21252;
sum%=21252;
if(sum==0)
sum=21252;
printf("%lld\n",sum);
return 0;
}
//輸入:283 102 23 320
2.
//2003.4.2
#include <stdio.h>
int main(){
const int u[4]={0,5,3,1};
const int v[4]={0,7,6,5};
int a,b,c,d,e,f,x,y,z;
scanf("%d%d%d%d%d%d",&a,&b,&c,&d,&e,&f);
z=f+e+d+(c+3)/4;
y=5*d+u[c%4-1];
if(b>y){
z=z+(b-y+8)/9;
x=((b-y+8)/9*9-(b-y))*4+11*e+v[c%4-1];
}else
x=(y-b)*4+11*e+v[c%4-1];
if(a>x)
z=z+(a-x+35)/36;
printf("%d\n",z);
return 0;
}
//輸入:4 7 9 20 56 47
3.
//2003.4.3
//原文有殘缺,上網搜索
#include <stdio.h>
int m,n;
int mark;
int test(int m,int n){
int i,p;
int flag;
int ans;
m--;
i=0;
flag=0;
for(p=2*n;p>=n+1;p--){
i=(i+m)%p;
if(i<n){//此處原文if(i
flag=1;
ans=0;
break;
}
}
if(!flag)
ans=1;
return ans;
}
int main(){
scanf("%d",&n);
m=1;
mark=0;
do{
if(test(m,n)==1){
printf("%d\n",m);
break;
}
m++;
}while(mark==0);//此處原文until mark
return 0;
}
//輸入:7
4.
//2003.4.4
#include <stdio.h>
int main(){
int m,n,i,j;
int p[20],w[20],a[20],b[20];
scanf("%d",&n);
m=0;
for(i=0;i<=n-1;i++){
scanf("%d",&p[i]);
b[i]=1;
}
for(i=0;i<=n-1;i++){
if(i>0)
a[m]=p[i]-p[i-1];
else
a[m]=p[i];
m++;
while(m>1&&a[m-1]==0){
m--;
b[m]=1;
}
if(m>0)
w[i]=b[m-1];
else
w[i]=b[0];
a[m-1]--;
for(j=0;j<=m-1;j++)
b[j]++;
while(m>1&&a[m-1]==0){
m--;
b[m]=1;
}
}
for(i=0;i<=n-1;i++)
printf("%d ",w[i]);
printf("\n");
return 0;
}
//輸入:9
//4 6 6 6 6 8 9 9 9
問題解答:
1.代碼比較短的題目,要麼難在遞歸,要麼難在數學。
sum=(7*5544+18*14421+23*1288-320+21252)%21252
看到這,馬上就不想算,有沒簡便的方法,突然發現14421,5544,1288好像有聯繫。
21252-14421=6831
6831-5544=1287
立馬改造上式
sum=(18*(5544+14421+1287)-11*5544+18*1+5*1288-320+21252)%21252
sum=(-11*5544+18*1+5*1288-320)%21252
sum=(-60984+18+6440-320)%21252等價於sum=(21252*3-60984+18+6440-320)%21252
sum=8910%21252
sum=8910.
答案:8910
1簡單
2.順着程序執行,很快就能得到答案
中間過程如下:
z=126
y=100
7>100
else
x=988
4>988
執行printf語句。
答案:126
2簡單
3.程序意思很快能看懂,但手工算卻算不出。搜索網絡:
受https://zhidao.baidu.com/question/326602498.html啓發開始研究約瑟夫問題,
這兩段可以大致推測,這道題的題意是改編版的約瑟夫問題,即有N個好人,N個壞人,好人編號1~N,壞人編號N+1~2*N,求最小的M使先出圈的N個人都是壞人。
找到http://blog.sina.com.cn/s/blog_644817fd0100wo35.html可惜是程序算出。
研究手工算法。
暫無辦法,機器算出的答案是1872。
3難
4.程序塊位置敲錯,以及沒注意到該程序有兩行輸入,折騰了好半天,一直以爲題目有誤,結果題目沒有問題。
重新開始做。一直覺得b[i]=1;有點怪,應該是b[i]=0;不過經驗證,題目無誤。
程序難在比較繁,一不小心就容易出錯,思路簡單,按部就班。
程序執行過程如下:
答案:1 1 2 4 5 1 1 3 9(空格分隔)
2016-12-15 21:21
4難