return0;
}
输入:
8
继续模拟,while语句中函数调用细心点即可。
输出:
7
输入:
2012
对前面的模拟进行观察,得出如下规律后计算:
i=2012=512+256+128+64+16+8+4
即data[1]=512data[2]=256data[3]=128data[4]=64data[5]=16data[6]=8data[7]=4
ans=512-1+256-1+128-1+64-1+16-1+8-1+4-1=2004
输出:
2004
NOIP2012-4.
#include
#include
using namespace std;
intlefts[20],rights[20],father[20];
strings1,s2,s3;
intn,ans;
voidcalc(int x,int dep)
{
ans=ans+dep*(s1[x]-'A'+1);
if(lefts[x]>=0)calc(lefts[x],dep+1);
if(rights[x]>=0)calc(rights[x],dep+1);
}//递归函数,返回ans,累计结点深度*结点权值之和
voidcheck(intx)
{
if(lefts[x]>=0)check(lefts[x]);
s3=s3+s1[x];
if(rights[x]>=0)check(rights[x]);
}
voiddfs(intx,intth)
{
if(th==n)
{
s3="";
check(0);
if(s3==s2)
{
ans=0;
calc(0,1);
cout<}//输出递归函数calc(0,1)的值
return;
}
if(lefts[x]==-1&&rights[x]==-1)
{
lefts[x]=th;
father[th]=x;
dfs(th,th+1);
father[th]=-1;
lefts[x]=-1;
}
if(rights[x]==-1)
{
rights[x]=th;
father[th]=x;
dfs(th,th+1);
father[th]=-1;
rights[x]=-1;
}
if(father[x]>=0)
dfs(father[x],th);
}
intmain()
{
cin>>s1;//先序遍历序列
cin>>s2;//中序遍历序列
n=s1.size();
memset(lefts,-1,sizeof(lefts));
memset(rights,-1,sizeof(rights));
memset(father,-1,sizeof(father));
dfs(0,1);
}
输入:
ABCDEF
BCAEDF
这是二叉树的遍历题,先根据两个输入的遍历序列确定二叉树。
再根据递归函数计算六个结点深度*权值之和:
ans=1*1+2*2+3*3+4*2+5*3+6*3
输出:
55
NOIP2013-1.
#include
#include
usingnamespace std;
intmain()
{
stringStr;
cin>>str;
int n=str.size( );
bool isPlalindrome=true;
for(int i=0;iif(str[i]!
=str[n-i-1]) isPlalindrome=false;
}
if(isPlalindrome)
cout<<”Yes”<else
cout<<”No”<}
输入:
abceecba
判断输入的是不是一个回文串,字符串左右颠倒,结果不变。
输出:
Yes
NOIP2013-2.
#include
usingnamespacestd;
intmain()
{
int a,b,u,v,i,num;
cin>>a>>b>>u>>v;
num =0;
for (i=a;I<=b; i++)
if(((i%u)==0)||((i%v)==0))
num++;
count<return 0;
}
输入:
1 10001015
1-1000范围内同时是10、15的倍数有多少?
注意去重。
输出:
133
NOIP2013-3.
#include
usingnamespacestd;
intmain()
{
const int SIZE=100;
int height[SIZE], num[SIZE], n,ans;
cin>>n;
for (int i=0; icin>>height[i];
num[i]=1;
for (int j=0; j
if((height[j]=num[i]))
num[i]=num[j]+1;
}
}
ans=0;
for(int I=1; iif(num[i]>ans)ans=num[j];
}
cout<return0;
}
输入:
8
32511127410
求该字符串的最长上升子序列的长度。
输出:
4
NOIP2013-4.
#include
#include
usingnamespace std;
const int SIZE=100;
int n, m, p, a[SIZE][SIZE],count;
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((xcolour(x+1,y);
if((ycolour(x,y+1);
}
intmain()
{
int i, j, x, y,ans;
memset(a, 0, sizeof(a));
cin>>n>>m>>p;
for(i=1;I<=p; i++){
cin>>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 (ansans}
count<return 0;
}
输入:
659
14
23
24
32
41
43
45
54
64
根据输入的x和y值画出0-1矩阵,再判断同一区域0最多的个数
输出:
7
NOIP2014-1.
#include
usingnamespacestd;
intmain()
{
inta,b,i,tot,c1,c2;
cin>>a>>b;
tot=0;
for(i=a;i<=b;i++)
{
c1=i/10;
c2=i%10;
if((c1+c2)%3==0)
tot++; //一个数的各位数之和是3的倍数,它就是3的倍数。
}
cout<return0;
} //统计7-31之间有多少数是3的倍数
输入:
7 31
输出:
8
NOIP2014-2.
#include
usingnamespacestd;
intfun(intn,intminNum,intmaxNum)
{
inttot,i;
if(n==0)
return1;
tot=0;
for(i=minNum;i<=maxNum;i++)
tot+=fun(n-1,i+1,maxNum);
returntot;
}
intmain()
{
intn,m;
cin>>n>>m;
cout<return0;
}
输入:
6 3
递归边界:
当n=0时,fun(n,minNum,maxNum)=1
fun(3,1,6)=(2,2,6)+(2,3,6)+(2,4,6)+(2,5,6)+(2,6,6)+(2,7,6)=20
fun(2,2,6)=(1,3,6)+(1,4,6)+(1,5,6)+(1,6,6)+(1,7,6)=10
fun(2,3,6)=(1,4,6)+(1,5,6)+(1,6,6)+(1,7,6)=6
fun(2,4,6)=(1,5,6)+(1,6,6)+(1,7,6)=3
fun(2,5,6)=(1,6,6)+(1,7,6)=1
fun(2,6,6)=(1,7,6)=0
fun(1,3,6)=(0,4,6)+(0,5,6)+(0,6,6)+(0,7,6)=4
fun(1,4,6)=(0,5,6)+(0,6,6)+(0,7,6)=3
fun(1,5,6)=(0,6,6)+(0,7,6)=2
fun(1,6,6)=(0,7,6)=1
fun(1,7,6)=0
输出:
20
NOIP2014-3.
#include
#include
usingnamespacestd;
constintSIZE=100;
intmain()
{
stringdict[SIZE];
intrank[SIZE];
intind[SIZE];
inti,j,n,tmp;
cin>>n;
for(i=1;i<=n;i++){
rank[i]=i;
ind[i]=i;
cin>>dict[i];
}
for (i=1;ifor(j=1;j<=n-i;j++)
if(dict[ind[j]]>dict[ind[j+1]]){
tmp=ind[j];
ind[j]=ind[j+1];
ind[j+1]=tmp;
}//冒泡排序
for(i=1;i<=n;i++)
rank[ind[i]]=i;//输出dict里字符排序后应该在的位置
for(i=1;i<=n;i++)
cout<cout<return0;
}
输入:
7
aaa
aba
bbb
aaa
aaa
ccc
aa
输出:
2563471
NOIP2014-4.
#include
usingnamespacestd;
constintSIZE=100;
intalive[SIZE];
intn;
intnext(intnum)
{
do{
num++;
if(num>n)
num=1;
}while(alive[num]==0);
returnnum;
}
intmain()
{
intm,i,j,num;
cin>>n>>m;
for(i=1;i<=n;i++)
alive[i]=1;
num=1;
for(i=1;i<=n;i++){
for(j=1;jnum=next(num);
cout<alive[num]=0;
if(inum=next(num);
}
cout<return0;
}
输入:
113
这就是约瑟夫环问题,11个人围一圈,从1开始报数,报到3的出局,再从出局的下一个人开始报1,直到全部出局,依次输出出局人的编号。
输出:
3691510411827
NOIP2015-1.//同普及组阅读题NOIP2015-2
#include
usingnamespacestd;
structpoint{
intx;
inty;
};
intmain()
{
structEX{
inta;
intb;
pointc;
}e;
e.a=1;
e.b=2;
e.c.x=e.a+e.b;
e.c.y=e.a*e.b;
cout<