完善程序题 普及篇(1-8题)

1.[NOIP1998]分割单词

/*
完善程序题 普及篇 1.[NOIP1998]分割单词
四、根据题意,补充完善以下程序:(14%)
输入一长度不超过80个字符的字符串(称为源串),
该字符串由小写英文字母、空格组成,并以'.'结束。
单词是由连续字母组成,两个单词之间至少有一个空格。
本程序的功能为:首先找出字符串中所有单词并保留一个空格作为单词分隔,
存入数组ch中。然后用键盘输入一个待查找的单词,
以字符'$'结束。采用顺序查找的方法在ch中进行查找,若找到,
则输出该单词在ch中出现的序号(若有多个位置出现该单词,则只输出第一个序号位置)。
若不存在,则输出'NOT FOUND'。
程序如下:(14%) 
*/
#include <iostream>
#include <cstdio>
using namespace std;
char a[85],b[85],ch[85];
int i,j,k,n,m;
int main( )
{
	n=0;
	do
	{
		__(1)___;a[n]=getchar();
	}while(a[n]!='.');
	k=0;
	for(i=1;i<=n;++i)
		if(a[i]>='a'&& a[i]<='z')
		{
			k++;
			___(2)___;
		}else if(k!=0)
			if(ch[k]!='')
			{
				k++;ch[k]='';
			}
	m=0;___(3)___;
	do
	{
		m++;b[m]=getchar();
	}while( __(4)__);
	i=1;j=1;k=1;b[m]='';
	while(i<=n && j<=m)
	{
		if( __(5)__ )
		{
			i++;j++;
		}
		else
		{
			while( ch[i]!='') i=i+1;
			i=i+1;j=1;k++;
		}
	}
	if( __ (6)___ )
	{
		printf("%d",k);
	}
	else printf("NOT FOUND");
	
	return 0;
}
/*
答案:
(1)、n=n+1
(2)、ch[k]=a[i]
(3)、n=k
(4)、b[m]!='$'
(5)、 ch[i]==b[j]
(6)、j>m-1 
*/

 完善程序题 普及篇 2、【NOIP1998】FBZ串问题

完善程序题 普及篇 2、【NOIP1998】FBZ串问题_dllglvzhenfeng的博客-CSDN博客


 3.[NOIP1999]全排列

/*
完善程序题 普及篇 3.[NOIP1999]全排列 
[问题描述] 
  	用生成法求出1,2,…,r的全排列(r<=8)
[程序说明] 
	用数组:a[r+1]表示排列;
	初始化时,a[i]=1(i=1,2,….r)
	设中间的某一个排列为a[1],a[2],…a[r]
	则求出下一个排列的算法为:
	(1) 从后面向前找,直到找到一个顺序为止(设下标为j-1,则a[j-1]<a[j]
	(2) 从a[j]- a[r]中,找出一个a[k]比a[j-1]大的最小元素
	(3) 将a[j-1]与a[k]交换
	(4) 将a[j],a[j+1]……a[r]由小到大排序。                
[程序清单]
*/
#include <iostream>
#include <cstdio>
using namespace std;
const int r=7;
int n,i,s,k,j,i1,t,a[r+1];
void print1(){
	int ik;
	for(ik=1;ik<=r;++ik) cout<<" "<<a[ik];
	cout<<endl;
}
int main( ){
	for(i=1;i<=r;++i) ___(1)____;
	print1();
	s=1;
	for(i=2;i<=r;++i) s=s*i;
	s=s-1;
	for(i=__(2)___;++i){
		j=r;
		while( __(3)___ ) j=j-1;
		k=j;
		for(i1=j+1;i1<=r;++i1)
			if( __(4)___ ) k=i1;
		t=a[j-1];a[j-1]=a[k];a[k]=t;
		for(i1=j;i1<=r-1;++i1)
			for(k=i1+1;k<=r;++k)
				if( ___(5)___ ){
					t=a[i1];a[i1]=a[k];a[k]=t;
				}
		print1();
	}
	return 0;
}
/*
答案:
(1)、a[i]=i
(2)、l;i<=s
(3)、a[j-1]>a[j]
(4)、a[i1]>a[j-1]&&a[i1]<a[k]
(5)、a[i1]>a[k] 
*/

4.[NOIP2000]多项式的乘法

/*
4.[NOIP2000]多项式的乘法。
   例如有如下多项式:
         P(X)=2X2-X+1,   Q(X)=X+1
   则:
         P(X)·Q(X)=(2X2-X+1)(X+1)=2X3+X2+1
   
  程序说明:
    多项式的表示:系数、指数
    如上例中:    P(X):  系数   指数          Q(X)    系数     指数
                            2       2                     1       1
                            -1  	 1                     1       0
                            1       0                     0       0
                            0       0
    PXQ的结果存入C中。其输出格式是:依次用一对括号内的(系数,指数)分别来表示。如上例的输出结果表示为:(2,3)(1,2)(1,0)
程序清单
*/
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int p[15][5],q[15][5],c[25][5];
int main()
{
	int i,j,k,l,jp,jq,jc,x,y,x1,y1;
	jp=0;
	cin>>x>>y;
	while( x!=0 )
	{
		jp++;
		p[jp][1]=x;
		p[jp][2]=y;
		cin>>x>>y;
	}
	jq=0;
	cin>>x>>y;
	while( x!=0)
	{
		jq++;
		q[jq][1]=x;
		q[jq][2]=y;
		cin>>x>>y;
	}
	jc=1;
	c[jc][1]=0;
	c[jc][2]=-1000;
	for(i=1;i<=jp;i++)
	{
		___(1)____;
		y=p[i][2];
		for(j=1;j<=jq;j++)
		{
			___(2)____;
			y1=y+q[j][2];
			k=1;
			while(y1<c[k][2]) k++;
			if(y1==c[k][2]) ___(3)____;
			else{
				for(l=jc;j>=k;l--)
				{
					c[l+1][1]=c[l][1];
					c[l+1][2]=cp[1][2];
				}
				c[k][1]=x1;
				c[k][2]=y1;
				__(4)___;
			}
		}
	}
	for(int i=1;i<=jc;i++)
		if( __(5)___ ) cout<<'('<<c[i][1]<<','<<c[i][2]<<')';
	return 0;
}
/*
答案:
(1)、x=p[i][1]
(2)、 x1=x*q[j][1]
(3)、c[k][1]=c[k][1]+x1 
(4)、jc=jc+1或jc++ 
(5)、 c[i][1]!=0 
*/

 5.[NOIP2004]Joseph

/*
5.[NOIP2004]Joseph
题目描述:
原始的Joseph问题的描述如下:有n个人围坐在一个圆桌周围,把这n个人依次编号为1,…,n。从编号是1的人开始报数,数到第m个人出列,然后从出列的下一个人重新开始报数,数到第m个人又出列,…,如此反复直到所有的人全部出列为止。比如当n=6,m=5的时候,出列的顺序依次是5,4,6,2,3,1。
现在的问题是:假设有k个好人和k个坏人。好人的编号的1到k,坏人的编号是k+1到2k。我们希望求出m的最小值,使得最先出列的k个人都是坏人。
输入:
仅有的一个数字是k(0 < k <14)。
输出:
使得最先出列的k个人都是坏人的m的最小值。
输入样例:
4
输出样例:
30
程序:
*/
#include <stdio.h>
long k, m, begin;
int check(long remain){
	long result = (  ①  ) % remain;
	if (  ②  ){
		begin = result; return 1;
	}
	else return 0;
}
int main(){
	long i, find = 0;
	scanf("%ld", &k);
	m = k;
	while(  ③  ) {
		find = 1; begin = 0;
		for (i = 0; i < k; i++)
			if (!check(  ④  )){
				find = 0; break;
			}
		m++;
	}
	printf("%ld\n",   ⑤  );
	return 0;
}
/*
答案:
(1)、begin+m-1
(2)、result>=k(或者k<=result) 
(3)、!find(或者find==0) 
(4)、2*k-i
(5)、m-1
*/

6、NOIP2006普及组初赛4.2

/*
NOIP2006普及组初赛4.2
2.  由键盘输入一个奇数 P (P<100,000,000),
其个位数字不是 5,求一个整数 S,
使 P×S =1111...1 ( 在给定的条件下,解 S 必存在)。
要求在屏幕上依次输出以下结果: 
(1)S 的全部数字。除最后一行外,每行输出 50 位数字。 
(2) 乘积的数字位数。 
 
 例1:输入p=13,由于13*8547=111111,
 则应输出
 (1)8547,
 (2)6 

 例2输入p=147,则输出结果应为
(1)755857898715041572184429327286470143613 
(2)42,即等式的右端有42个1。 
 
程序:
*/ 
#include <iostream.h> 
#include <iomanip.h> 
void main() 
{
	long p,a,b,c,t,n; 
	while (1) 
    { 
		cout <<"输入 p, 最后一位为 1 或 3 或 7 或 9:"<<endl; 
      	cin >>p; 
      	if ((p%2!=0)&&(p%5!=0))  // 如果输入的数符合要求,结束循环 
              ⑥   ; 
	}
   	a=0; n=0; 
   	while (a<p)   
	{	a=a*10+1; 
		n++;         // 变量a存放部分右端项,n为右端项的位数  
    } 
   	t=0; 
   	do 
    {
		b=a/p;   
    	cout <<setw(1)<<b; 
    	t++; 
     	if (   ⑦   ) 
        	cout <<endl; 
       	c=   ⑧   ;  
		a=   ⑨   ; 
		n++; 
    } while (c>0); 
   	cout<<endl<<"n="<<   ⑩   <<endl; 
} 
/*
答案:
(1)、break
(2)、t%50==0
(3)、a-p*b(或a-b*p) 
(4)、c*10+1
(5)、--n 
*/

完善程序 普及篇 7、【NOIP2006提高组】(选排列)

https://blog.csdn.net/dllglvzhenfeng/article/details/130987431


8、NOIP 2007提高组初赛试题完善程序题 5.1(格雷码,Gray Code)

/*
NOIP 2007提高组初赛试题完善程序题5.1(格雷码,Gray Code)
(格雷码,Gray Code)
格雷码是对十进制数的一种二进制编码。
编码顺序与相应的十进制数的大小不一致。其特点是:对于
两个相邻的十进制数,对应的两个格雷码只有一个二进制位不同。
另外,最大数与最小数之间也仅有一个
二进制位不同,以4 位二进制数为例,编码如下:

如果把每个二进制的位看作一个开关,
则将一个数变为相邻的另一个数,只须改动一个开关。因此,
格雷码广泛用于信号处理、数-模转换等领域。
下面程序的任务是:由键盘输入二进制数的位数n (n<16),
再输入一个十进制数m(0≤m<2n),然
后输出对应于m 的格雷码(共n 位,用数组gr[]存放)。

为了将程序补充完整,你必须认真分析上表的规律,
特别是对格雷码固定的某一位,从哪个十进制数
起,由0 变为1,或由1 变为0。
*/
#include <iostream.h>
#include <iomanip.h>
void main()
{
	int bound=1,m,n,i,j,b,p,gr[15];
	cout<<"Input n,m:"<<endl;
	cin>>n>>m;

	for(i=1;i<=n;i++) bound= ①;

	if(m<0||m>=bound)
	{
		cout<<"Data error!"<<endl;
		②;
	}
	b=1;
	for(i=1;i<=n;i++)
	{
		p=0; b=b*2;
		for( ③ ; j<=m;j++)
			if(	④)
				p=1-p;
		gr[i]=p;
	}

	for(i=n;⑤)
		cout<<setw(1)<<gr[i];
	cout<<endl;
	return 0;
}
/*
答案:
(1)、bound*2
(2)、return或exit(0) 
(3)、j=0
(4)、(j%b-(b/2))==0
(5)、 i>=1;i--或i>0;i-- 
*/

 


 


 


大量写题是很重要的。特别是对于参加NOI等赛事的选手而言,不应拘泥于一本书或者一个题库,而是应根据自己的实际需求,广泛涉猎自己需要的资源。

对于没有任何编程基础的读者,建议从头按章节顺序学习。如果有一定的基础,那么可以选择性地阅读其中希望进一步巩固的部分,除了第1部分外,后面部分的各章节相对独立,读者可以根据实际情况自行安排学习顺序。

保证程序正确:培养一次写对的能力,提交评测之前要谨慎。学会怎样调试自己的程序。就算感觉对拍办不到,也应该人工生成多组数据,手算结果,然后测试自己的程序对不对。所有犯过的错误都要写笔记,并且不再犯第二次。

如果希望能够熟练掌握算法,增强思维敏捷性,在学习完算法与数据结构后,必须大量地完成相关的题目。

建议本书的读者花费半年的时间学完这本书,至少完成300题,且每周不少于10题。

本书给出的代码仅仅是用来参考的,千万不要照抄。

只有亲自动手实践,学到的东西才是自己的。

熟悉固定套路与算法模板:要反复地敲算法模板,从空白文件开始敲,直到一遍通过为止,这一点你必须很熟练

                                                           --------- 摘自《深入浅出程序设计竞赛(基础篇)》


我眼中的竞赛应该主要比思维和实践能力,而不是主要比见识。

大家都知道,编程需要大量的练习,只看和听是不够的。

反过来,如果只是盲目练习,不看不听也是不明智的。

本书的目标很明确---提供算法竞赛入门所必须的一切“看”的蓝本。

有效的“听”要靠教师的辛勤劳动,而有效的“练”则要靠学生自己。

              

                                                               --------- 摘自《算法竞赛入门经典(第2版)》

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dllglvzhenfeng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值