蓝桥杯练习题库 3算法训练之VIP题综述.docx
《蓝桥杯练习题库 3算法训练之VIP题综述.docx》由会员分享,可在线阅读,更多相关《蓝桥杯练习题库 3算法训练之VIP题综述.docx(259页珍藏版)》请在冰豆网上搜索。
蓝桥杯练习题库3算法训练之VIP题综述
算法训练黑白无常
时间限制:
1.0s 内存限制:
256.0MB
查看参考代码
问题描述
某寝室的同学们在学术完之后准备玩一个游戏:
游戏是这样的,每个人头上都被贴了一张白色或者黑色的纸,现在每个人都会说一句话“我看到x张白色纸条和y张黑色的纸条”,又已知每个头上贴着白色纸的人说的是真话、每个头上贴着黑色纸的人说的是谎话,现在要求你判断哪些人头上贴着的是白色的纸条,如果无解输出“NoSolution.”;如果有多组解,则把每个答案中贴白条的人的编号按照大小排列后组成一个数(比如第一个人和第三个人头上贴着的是白纸条,那么这个数就是13;如果第6、7、8个人都贴的是白纸条,那么这个数就是678)输出最小的那个数(如果全部都是黑纸条也满足情况的话,那么输出0)
输入格式
第一行为一个整数n,接下来n行中的第i行有两个整数x和y,分别表示第i个人说“我看到x张白色纸条和y张黑色的纸条”。
输出格式
一行。
如果无解输出“NoSolution.”。
否则输出答案中数值(具体见问题描述)最小的那个,如果全部都是黑纸条也满足情况的话,那么输出0
样例输入
2
10
10
样例输出
0
样例输入
5
31
04
13
40
13
样例输出
35
数据规模和约定
n<=8
#include
#include
intn;
intx[8],y[8];
intisok(inta[],intnum,intvalue)//第i个人的话是否成立num为人下标value为0白或者1黑
{
intblack=0,white=0,i;
for(i=0;i{
if(i!
=num)
{
if(a[i])black++;//黑色
elsewhite++;//白色
}
}
if(value)//黑
{
if(x[num]==white&&y[num]==black)return0;
elsereturn1;
}
else//白
{
if(x[num]==white&&y[num]==black)return1;
elsereturn0;
}
}
intmain()
{
inti,j,k,sign,min=90000000,num;
inta[8],b[8];
scanf("%d",&n);
for(i=0;iscanf("%d%d",x+i,y+i);
for(i=0;i{
k=i;
for(j=0;j{
a[j]=k%2;
k/=2;
}
sign=1;
for(j=0;j{
if(isok(a,j,a[j])==0)
{
sign=0;
break;
}
}
if(sign)
{
k=1;
num=0;
for(j=n-1;j>=0;j--)
{
if(a[j]==0)
{
num+=k*(j+1);
k*=10;
}
}
if(num}
}
if(min==90000000)printf("NoSolution.");
else
{
for(i=0;ib[i]=1;
for(i=0;i{
if(isok(b,i,b[i])==0)
{
sign=0;
break;
}
}
if(sign==0)printf("%d",min);
elseprintf("0");
}
return0;
}
#include
#include
#include
intmt[9][2],n;
intmax[9]={9};
intxl[9]={9};
boolifc();
intmain()
{
inti,j,m,fi,k,flag;
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d%d",&mt[i][0],&mt[i][1]);
m=pow(2,n);
for(i=0;i{
for(fi=i,j=1,xl[0]=0;j<=n;j++)
{
xl[j]=fi&1;
fi>>=1;
if(xl[j])xl[0]++;//真话数量
}
if(xl[0]>max[0])continue;
if(ifc())//成立
{
//for(k=1;k<=n;k++)printf("%d",xl[k]);
//printf(":
%d\n",xl[0]);
if(max[0]==xl[0])
{
for(flag=k=1;k<=n;k++)
{
if(max[k]>xl[k])
{
flag=0;
break;
}
elseif(max[k]{
break;
}
}
if(!
flag)continue;
}
for(k=0;k<=n;k++)max[k]=xl[k];
}
}
if(max[0]==9)printf("NoSolution.\n");
elseif(max[0]==0)printf("0\n");
else
{
for(i=1;i<=n;i++)if(max[i])printf("%d",i);
putchar('\n');
}
}
boolifc()
{
inti;
for(i=1;i<=n;i++)
{
if(xl[i])//若此人说真话
{
if(mt[i][0]!
=xl[0]-1)returnfalse;
}
else
{
if(mt[i][0]==xl[0])returnfalse;
}
}
returntrue;
}
算法训练数的统计
时间限制:
1.0s 内存限制:
256.0MB
查看参考代码
问题描述
在一个有限的正整数序列中,有些数会多次重复出现在这个序列中。
如序列:
3,1,2,1,5,1,2。
其中1就出现3次,2出现2次,3出现1次,5出现1次。
你的任务是对于给定的正整数序列,从小到大依次输出序列中出现的数及出现的次数。
输入格式
第一行正整数n,表示给定序列中正整数的个数。
第二行是n个用空格隔开的正整数x,代表给定的序列。
输出格式
若干行,每行两个用一个空格隔开的数,第一个是数列中出现的数,第二个是该数在序列中出现的次数。
样例输入
12
828221111811313
样例输出
13
23
83
111
132
数据规模和约定
数据:
n<=1000;0#include
intmain()
{
inti,m,n,a[1000],count=0,totalcount=0;
scanf("%d",&n);
for(i=0;iscanf("%d",&a[i]);
for(m=1;totalcount{
count=0;
for(i=0;iif(a[i]==m)
{
count++;
totalcount++;
}
if(count!
=0)
{
printf("%d%d",m,count);
printf("\n");
}
}
return0;
}
#include
#include
#include
usingnamespacestd;
intmain()
{
inta[1000],i,j=0,b[1000]={0},n,sum=1,x=0;
scanf("%d",&n);
for(i=0;isort(a,a+n);
for(i=0;i{
if(a[i]==a[i+1])sum++;
elseb[j++]=sum,sum=1;
}
for(i=0;i{
x+=b[i];
printf("%d%d\n",a[x-1],b[i]);
}
return0;
}
算法训练暗恋
时间限制:
1.0s 内存限制:
256.0MB
查看参考代码
问题描述
同在一个高中,他却不敢去找她,虽然在别人看来,那是再简单不过的事。
暗恋,是他唯一能做的事。
他只能在每天课间操的时候,望望她的位置,看看她倾心的动作,就够了。
操场上的彩砖啊,你们的位置,就是他们能够站立的地方,他俩的关系就像砖与砖之间一样固定,无法动摇。
还记得当初铺砖的工人,将整个操场按正方形铺砖(整个操场可视为R行C列的矩阵,矩阵的每个元素为一块正方形砖块),正方形砖块有两种,一种为蓝色,另一种为红色。
我们定义他和她之间的“爱情指标”为最大纯色正方形的面积,请你写一个程序求出“爱情指标”。
输入格式
第一行两个正整数R和C。
接下来R行C列描述整个操场,红色砖块用1来表示,蓝色砖块用0来表示。
输出格式
一个数,表示他和她之间的“爱情指标”。
样例输入
58
00011101
11011111
01111101
10111110
11101101
样例输出
9
数据规模和约定
40%的数据R,C<=10;
70%的数据R,C<=50;
100%的数据R,C<=200;
#include
ints[200][200];
intispure(intx1,inty1,intw)//w为宽度
{
inti,j,pure=s[x1][y1];
for(i=0;ifor(j=0;jif(s[x1+i][y1+j]!
=pure)return0;
return1;
}
intmain()
{
intr,c,i,j,w;
intmax=0,m;
scanf("%d%d",&r,&c);
if(r>c)m=r;
elsem=c;
for(i=0;ifor(j=0;jscanf("%d",&s[i][j]);
for(i=0;ifor(j=0;j{
for(w=max+1;w{
if(i+w<=r&&j+w<=c)
{
if(ispure(i,j,w))max=w;
}
elsebreak;
}
}
printf("%d",max*max);
return0;
}
#include
#include
#include
usingnamespacestd;
intr,c;
intarea(inta[200][200],inti,intj,intn)
{
intk,l;
if(n==min(r-1,c-1))
returnn;
else
{
for(k=0;k<=n;k++)
{
if(a[i+n][j+k]!
=a[i][j])
{
returnn;
}
}
for(l=0;l{
if(a[i+l][j+n]!
=a[i][j])
returnn;
}
area(a,i,j,++n);
}
}
intmain()
{
//freopen("input3
(1).txt","r",stdin);
inti,j,max=0,n=1,s;
scanf("%d%d",&r,&c);
inta[200][200]={-1};
//memset(a,-1,sizeof(a));
for(i=0;i{
for(j=0;jscanf("%d",&a[i][j]);
}
//for(i=0;i//{
//for(j=0;j//printf("%d",a[i][j]);
//printf("\n");
//}
for(i=0;i{
for(j=0;j{
n=area(a,i,j,1);
if(n>max)max=n;
//printf("a[%d][%d]=%d\n",i,j,n);
if(max>=c/2)
break;
}
if(max>=r/2)
break;
}
printf("%d",max*max);
return0;
}
算法训练明明的随机数
时间限制:
1.0s 内存限制:
256.0MB
查看参考代码
问题描述
明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。
然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。
请你协助明明完成“去重”与“排序”的工作。
输入格式
输入有2行,第1行为1个正整数,表示所生成的随机数的个数:
N
第2行有N个用空格隔开的正整数,为所产生的随机数。
输出格式
输出也是2行,第1行为1个正整数M,表示不相同的随机数的个数。
第2行为M个用空格隔开的正整数,为从小到大排好序的不相同的随机数。
样例输入
10
2040326740208930040015
样例输出
8
152032406789300400
题目来源
计13李震摘编自NOIP06PJ01
#include
ints[1000];
voidsort(inta[],intlen)
{
inti,j,min;
for(i=0;i{
min=i;
for(j=i+1;jif(a[j]j=a[i];a[i]=a[min];a[min]=j;
}
}
intmain()
{
intn,i,num=1;
scanf("%d",&n);
for(i=0;iscanf("%d",s+i);
sort(s,n);
for(i=1;iif(s[i]>s[i-1])num++;
printf("%d\n%d",num,s[0]);
for(i=1;iif(s[i]>s[i-1])printf("%d",s[i]);
return0;
}
#include
#include
usingnamespacestd;
intn,data;
sets;
intmain(){
inti;
cin>>n;
for(i=0;icin>>data;
s.insert(data);
}
cout<for(set:
:
iteratorit=s.begin();it!
=s.end();it++)
cout<<*it<<"";
cout<return0;
}
算法训练字符串的展开
时间限制:
1.0s 内存限制:
256.0MB
查看参考代码
在初赛普及组的“阅读程序写结果”的问题中,我们曾给出一个字符串展开的例子:
如果在输入的字符串中,含有类似于“d-h”或者“4-8”的字串,我们就把它当作一种简写,输出时,用连续递增的字母获数字串替代其中的减号,即,将上面两个子串分别输出为“defgh”和“45678”。
在本题中,我们通过增加一些参数的设置,使字符串的展开更为灵活。
具体约定如下:
(1)遇到下面的情况需要做字符串的展开:
在输入的字符串中,出现了减号“-”,减号两侧同为小写字母或同为数字,且按照ASCII码的顺序,减号右边的字符严格大于左边的字符。
(2)参数p1:
展开方式。
p1=1时,对于字母子串,填充小写字母;p1=2时,对于字母子串,填充大写字母。
这两种情况下数字子串的填充方式相同。
p1=3时,不论是字母子串还是数字字串,都用与要填充的字母个数相同的星号“*”来填充。
(3)参数p2:
填充字符的重复个数。
p2=k表示同一个字符要连续填充k个。
例如,当p2=3时,子串“d-h”应扩展为“deeefffgggh”。
减号两边的字符不变。
(4)参数p3:
是否改为逆序:
p3=1表示维持原来顺序,p3=2表示采用逆序输出,注意这时候仍然不包括减号两端的字符。
例如当p1=1、p2=2、p3=2时,子串“d-h”应扩展为“dggffeeh”。
(5)如果减号右边的字符恰好是左边字符的后继,只删除中间的减号,例如:
“d-e”应输出为“de”,“3-4”应输出为“34”。
如果减号右边的字符按照ASCII码的顺序小于或等于左边字符,输出时,要保留中间的减号,例如:
“d-d”应输出为“d-d”,“3-1”应输出为“3-1”。
输入格式
输入包括两行:
第1行为用空格隔开的3个正整数,一次表示参数p1,p2,p3。
第2行为一行字符串,仅由数字、小写字母和减号“-”组成。
行首和行末均无空格。
输出格式
输出只有一行,为展开后的字符串。
输入输出样例1
输入格式
输出格式
121
abcs-w1234-9s-4zz
abcsttuuvvw1234556677889s-4zz
输入输出样例2
输入格式
输出格式
232
a-d-d
aCCCBBBd-d
输入输出样例3
输入格式
输出格式
342
di-jkstra2-6
dijkstra2************6
数据规模和约定
40%的数据满足:
字符串长度不超过5
100%的数据满足:
1<=p1<=3,1<=p2<=8,1<=p3<=2。
字符串长度不超过100
#include
#include
#include
voidfill(chara)
{
}
intmain()
{
chars[120]={0};
memset(s,0,sizeof(s));
intp1,p2,p3,i,j,k;
scanf("%d%d%d",&p1,&p2,&p3);
scanf("%s",s);
for(i=0;i{
if(s[i]=='-')
{
if(s[i-1]>='a'&&s[i-1]<='z'&&s[i+1]>='a'&&s[i+1]<='z'&&s[i+1]>s[i-1]
||s[i-1]>='0'&&s[i-1]<='9'&&s[i+1]>='0'&&s[i+1]<='9'&&s[i+1]>s[i-1])
{
if(p1==3)
{
for(j=1;j<=p2*(s[i+1]-s[i-1]-1);j++)
{
printf("*");
}
}
else
{
if(s[i-1]>='0'&&s[i-1]<='9'&&s[i+1]>='0'&&s[i+1]<='9')
{
if(p3==1)
{
for(j=s[i-1]+1;j<=s[i+1]-1;j++)
{
for(k=1;k<=p2;k++)
{
printf("%c",j);
}
}
}
else
{
for(j=s[i+1]-1;j>=s[i-1]+1;j--)
{
for(k=1;k<=p2;k++)
{
printf("%c",j);
}
}
}
}
else
{
if(p3==1)
{
for(j=s[i-1]+1;j<=s[i+1]-1;j++)
{
for(k=1;k<=p2;k++)
{
printf("%c",p1==1?
j:
j-32);
}
}
}
else
{
for(j=s[i+1]-1;j>=s[i-1]+1;j--)
{
for(k=1;k<=p2;k++)
{
printf("%c",p1==1?
j:
j-32);
}
}
}
}
}
}
else
{
printf("%c",s[i]);
}
}
else
{
printf("%c",s[i]);
}
}
return0;
}
算法训练貌似化学
时间限制:
1.0s 内存限制:
256.0MB
查看参考代码
问题描述
现在有a,b,c三种原料,如果他们按x:
y:
z混合,就能产生一种神奇的物品d。
当然不一定只产生一份d,但a,b,c的最简比一定是x:
y:
z
现在给你3种可供选择的物品:
每个物品都是由a,b,c以一定比例组合成的,求出最少的物品数,使得他们能凑出整数个d物品(这里的最少是指三者个数的总和最少)
输入格式
第一行三个整数,表示d的配比(x,y,z)
接下来三行,表示三种