2017/4/2 hzu蓝桥杯练习

1.报纸页数

X星球日报和我们地球的城市早报是一样的,
都是一些单独的纸张叠在一起而已。每张纸印有4版。

比如,某张报纸包含的4页是:5,6,11,12,
可以确定它应该是最上边的第2张报纸。

我们在太空中捡到了一张X星球的报纸,4个页码分别是:
1125,1126,1727,1728

请你计算这份报纸一共多少页(也就是最大页码,并不是用了几张纸哦)?

请填写表示总页数的数字。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

这题说实话,我也没读懂,就空掉了,后来想不出来就直接百度,终于明白,大概的意思是:

一份报纸有很多页,然后正面和反面都有印刷内容,公式表示,假设最大页数是 8

第一张 的页码  正面1  2   反面 7  8 

第二张的页码   正面3  4   反面 5   6

所以这份报纸的只有两页,最大页码就是 8 了

根据这个关系可以计算出最大的页码

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
	int x=1125,nx=1126; //正面的页码 
	int y=1727,ny=1728; //反面的页面 
	while(nx+1!=y)//nx+1==y即是到了最后一页 
	{
		x++;
		nx++;
		y--;
		ny--;
	}
	printf("%d\n",2*nx); //最后一页的页码乘2就是最大页码
	return 0; 
}
6.

今有7对数字:两个1,两个2,两个3,...两个7,把它们排成一行。
要求,两个1间有1个其它数字,两个2间有2个其它数字,以此类推,两个7之间有7个其它数字。如下就是一个符合要求的排列:

17126425374635

当然,如果把它倒过来,也是符合要求的。

请你找出另一种符合要求的排列法,并且这个排列法是以74开头的。

注意:只填写这个14位的整数,不能填写任何多余的内容,比如说明注释等。

我的思路是这样:

1.因为题目已经规定了 7 和 4的位置,所以另外的 7 和 4 的位置也可以确定了

   像这样 7 4 # # # # 4 # 7 # # # # #,每一个#代表一个数字,从左到右编号1~14,所以现在就是要把剩余的10个数填到相应的位置上去

2.这里用数组的下标代表 1~14 等效代替 两对1~7,以7为一个周期,比如1 和 8等效,2和9等效,3和10等效用一个数组,数组下标表示 1~14 这14个数字,用数组元素的值表示他的位置,听起来很难理解

  比如  arr[1] =3 就表示 数字1 放在 位置3 ,,,arr[8]=9 代表数字 8 放在位置9

        # # 1 # # # # # 8 # # # # # ,

  8和1 是等效,于是就是

       # # 1 # # # # # 1 # # # # #

   显然两个1之间间隔超过1,所以这种情况不成立

3.像上面放1 和 8 的情况一样,用暴力枚举的形式,记住,我们现在是要赋给数字所在位置,在arr[15]这个数组的 1~14的下标表示1~14这些数字,遍历给他们填上位置

   比如arr[1]赋值3 arr[8]赋值为9,说明两个1之间 间隔 arr[8]-arr[1]-1=5个数,显然不符合,继续查找,直到找到符合条件的

哎,也不知道讲得清不清楚,其实这种方法速度很慢,怪我水平有限将就用把。

#include<stdio.h>
int a,b,c,d,e ,f,g,h,i,j;//十个位置未知 
int arr[15]; 
int pos[15];
int check()
{
	int i=1;
	while(i<=7)
	{
		if(arr[i+7]-arr[i]-1!=i)  
		//i+7和i是等价的,两个相同数字之间,间隔的数字个数等于 这两个数的位置之差-1,自己写一下就知道 
		//一对i之间要间隔i个数,所以要一旦有不满足这个条件,返回0 
		{
			return 0;
		}
		i++;	
	} 
	return 1;
}
void print()
{
	int i;
	for(i=1;i<15;i++)
	{
		pos[arr[i]]=i;  //arr[i]是数字i的地址,存放进pos数组后,pos数组就可以正常的顺序存放i了 
	}
	for(i=1;i<15;i++)
	{
		if(pos[i]>7){
			pos[i]=pos[i]-7;
		}
		printf("%d",pos[i]);
		
	}
	printf("\n");
}
int main()
{
	//题目给定了 7和4的位置 
	arr[7]=1;
	arr[14]=9;
	arr[4]=2;
	arr[11]=7;
	//分别给其他10个数赋上 地址 
	for(a=3;a<=14;a++)
	{
		arr[1]=a;
		
		for(b=3;b<=14;b++)
		{
			if(b==a||b==7||b==9)continue; 
			arr[2]=b;
			for(c=3;c<=14;c++)
			{
				if(c==a||c==b||c==7||c==9)continue;
				arr[3]=c;
				for(d=3;d<=14;d++)
				{
					if(d==a||d==b||d==c||d==7||d==9)continue;
					arr[5]=d;
					for(e=3;e<=14;e++)
					{
						if(e==a||e==b||e==c||e==d||e==7||e==9)continue;
						arr[6]=e;
						for(f=3;f<=14;f++)
						{
							if(f==a||f==b||f==c||f==d||f==e||f==7||f==9)continue;
							arr[8]=f;
							for(g=3;g<=14;g++)
							{
								if(g==a||g==b||g==c||g==d||g==e||g==f||g==7||g==9)continue;
								arr[9]=g;
								for(h=3;h<=14;h++)
								{
									if(h==a||h==b||h==c||h==d||h==e||h==f||h==g||h==7||h==9)continue;
									arr[10]=h;
									for(i=3;i<=14;i++)
									{
										if(i==a||i==b||i==c||i==d||i==e||i==f||i==g||i==h||i==7||i==9)continue;
										arr[12]=i;
										for(j=3;j<=14;j++)
										{
											if(j==a||j==b||j==c||j==d||j==e||j==f||j==g||j==h||j==i||j==7||j==9)continue;
											arr[13]=j;
											if(check()){ 
												print();
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
	return 0;
}
8

方阵的主对角线之上称为“上三角”。
请你设计一个用于填充n阶方阵的上三角区域的程序。填充的规则是:使用1,2,3….的自然数列,从左上角开始,按照顺时针方向螺旋填充。
例如:当n=3时,输出:
1 2 3
6 4
5
当n=4时,输出:
1  2 3 4
9 10 5
8  6
7
当n=5时,输出:
  1  2  3  4  5
 12 13 14  6
 11 15  7
 10  8
  9
程序运行时,要求用户输入整数n(3~20)
程序输出:方阵的上三角部分。
要求格式:每个数据宽度为4,右对齐。

思路:

先计算一共要打印多少个数字,然后先打印最外层那个三角形的数字,由外向内,每一个循环打印一层,并且每个循环结束改变一些参数,毕竟三角形要越变越小

#include<stdio.h>
int arr[50][50];
int n;
void print()
{
	int m=n;
	int i,j;
	for(i=0;i<n;i++)
	{
		for(j=0;j<m;j++)
		{
			printf("%4d",arr[i][j]);
		}
		m--;
		printf("\n");
	}
}
int main()
{
	scanf("%d",&n);
	int row=0;//从第0行开始向下写 
	int col=0;//从第0列开始向右写 
	int tmp=1;//要写的那个数字 
	int td=0; 
	int rd=n;
	int dd=n;
	int j,k;
	int r; 
	int all=n*(1+n)/2;  
	while(1)
	{
		for(j=col;j<rd;j++)
		{
			arr[row][j]=tmp;
			tmp++;
		}
		if(tmp>all){
			break;
		}
		int limit=rd-2;//有效位置
		for(r=row+1;tmp<=all&&r<dd&&limit>=0;limit--,r++) //斜的那一条 
		{
			arr[r][limit]=tmp;
			tmp++;
		}
		if(tmp>all){
			break;
		}
		for(j=dd-2;tmp<=all&&j>td;j--)
		{
			arr[j][col]=tmp;
			tmp++;
		}
		col=col+1; //改变列的起点 
		row=row+1;//改变行 
		rd=rd-2;//改变右边的边界 
		dd=dd-2;//底部每次上升两层 
		td++;//顶部向下降 
	}
	print();
	return 0; 
}
每周一练,或许这些题对于别人来说很简单,但我也希望一步一个脚印,让自己能够进步,加油。



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值