蓝桥杯选拔赛题解

A:LYC的女装

 题目要求得到的数是90的倍数,不难想到这题需要分析出90的倍数要满足什么条件。
首先对90进行质因数分解:90 = 2×3^2×5
得出2个结论: 
1.最后的数是偶数(废话)即最后一位一定要为0,如果手牌里没有0,那么只能输出-1
2.这个数要是3^2的倍数,即是9的倍数,可以推出组成这个数的各位数之和要是9的倍数,所以不用考虑0,只需要考虑5的个数,又因为9和5互质,所以每次需要取9个5才能保证这个数是9的倍数
 结合以上2个结论可以进行总结:
这个数是否是90的倍数和这个数各个位上的数字排列没有关系,只和组成这个数字的5,0的个数有关。 
如果手牌里没有0,那么输出-1(这点造数据的时候没有故意刁难,所以可能有人没有特判这点业过了)。
如果有0,那么并且5的个数小于9,那么输出0
如果有0,并且5个个数大于9,那么先输出count个5(5比0大,所以把5都先输出能保证最大)并且count要满足count%9==0&&count<5的个数,然后把0都输出(记得换行)

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
int main(void)
{
    int n;
    cin>>n;
    while(n--)
    {
        int a=0,b=0;
        int t;
        cin>>t;
        if(t==0)
            b++;
        else
            a++;
    }
    if(b==0)
        printf("-1\n");
    else if(a<9&&b!=0)
        printf("0\n");
    else
    {
        for(int i=0;i<a/9;i++)
            printf("555555555");
        for(int i=0;i<b;i++)
            printf("0");
        printf("\n");
    }
    return 0;
}

B:Zip好菜啊

主要考察各位同学对同一个描述对象有两个属性需要保存和使用的时候,选择什么方式来处理,以及对数组(当然你非要写链表或者用队列模拟这种小数据也不会卡你)从不同位置开始循环遍历的操作。比较简单,希望可以增进对取模运算在各种非数学操作时的使用方法的认识与理解。

#include <bits/stdc++.h>

#define ms(x, y) memset(x, y, sizeof(x))

using namespace std;
typedef long long LL;
typedef unsigned long long ULL;

const int maxn = 100003;
struct Node
{
    int r, c;
} nodes[110];
int main(int argc, char const *argv[])
{
    freopen("test.out", "w", stdout);
    freopen("test.in", "r", stdin);
    int T;
    scanf("%d", &T);
    while (T--)
    {
        int n;
        scanf("%d", &n);
        for (int i = 0; i < n; ++i)
            scanf("%d%d", &nodes[i].r, &nodes[i].c);
        bool ok;
        for (int start = 0; start < n; ++start)
        {
            ok = true;
            for (int i = start; i != (n + start - 1) % n; i = (i + 1) % n)
            {
                if (nodes[i].c != nodes[(i + 1) % n].r)
                {
                    ok = false;
                    break;
                }
            }
            if (ok) break;
        }
        if (ok) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

C:M爷的线段树

一个操作技巧,如果要在[l,r]区间中加+x,可以令s[l]=x,s[r+1]=-x
然后遍历  s[i]+=s[i-1]  (r<i<=r+1)

#include<bits/stdc++.h>

using namespace std;

const int maxn=1e5+5;

int a[maxn];
int b[maxn];

int main(int argc, char const *argv[])
{
 //   freopen("in.txt","r",stdin);
 //   freopen("out.txt","w",stdout);
    int n,m,k;
    while(~scanf("%d %d %d",&n,&m,&k))
    {
        if(n==-1&&m==-1&&k==-1) break;
        memset(b,0,sizeof(b));
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        int l,r,x;
        for(int i=1;i<=m;i++){
            scanf("%d %d %d",&l,&r,&x);
            b[l]+=x;b[r+1]-=x;
        }
        for(int i=1;i<=n;i++){
            b[i]+=b[i-1];
            a[i]+=b[i];
        }
        for(int i=1;i<=k;i++){
            scanf("%d",&x);
            printf("%d\n",a[x]);
        }
    }
    return 0;
}


D:美男有毒

#include <stdio.h>
#include <string.h>
char s[10][1024][2048];
int main()
{
    // freopen("test.in","r",stdin);
    // freopen("test.out","w",stdout);
    s[0][0][0]=s[0][1][1]=' ';
    s[0][0][1]=s[0][1][0]=s[0][1][2]='*';
    for(int n=1;n<10;++n)
    {
        int len=1<<n;
        for(int i=0;i<len;++i)
        {
            for(int j=0;j<len;++j)s[n][i][j]=' ';
            strcpy(s[n][i]+len,s[n-1][i]);
        }
        for(int i=0,x=len,y=len;i<len;++i,--x,++y)
        {
            strcpy(s[n][i+len],s[n-1][i]);
            for(int j=0;j<x;++j)s[n][i+len][j+y]=' ';
            strcpy(s[n][i+len]+(len<<1),s[n-1][i]);
        }
    }
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        int len=1<<(n+1);
        for(int i=0;i<len;++i)puts(s[n][i]);
    }
    return 0;
}

E:冰语大佬的游戏

 偶数个的时候拿1个是必胜,因为对方永远只能从奇数个中拿奇数个,能够保证自己的局面永远是偶数个
所以偶数必胜,奇数必输 

#include <cstdio>
int a[100010];
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        int res=0;
        for(int i=1;i<=n;i++){
            if(a[i]%2){
                res=i;
                break;
            }
        }
        if(res){
            printf("%d\n",res);
        }else{
            printf("bingyu is niu bi\n");
        }
    }
    return 0;
}

F:Poor Chtholly

对每个输入的A,若A出现过,输出第一次出现的时间,否则输出另一句话。唯一要注意的就是A可能为负数。桶索引整体偏移是最简单的。

#include <stdio.h>
int N, A, date[2000007];
int main()
{
    scanf("%d", &N);
    for(int i = 1; i <= N; ++i)
    {
        scanf("%d", &A);
        A += 1000003;
        if(date[A])
            printf("Don't forget the day %d. Have a good dream\n", date[A]);
        else
            printf("Fairy %d loves Chtholly\n", A - 1000003), date[A] = i;
    }
    return 0;
}
G:Hua Hua's birthday 

#include<stdio.h> 
int main()
{
	int n,i,a[31];
	a[1]=1;  
	a[2]=3;  
	for(i=3;i<=31;i++)   
	{
  		a[i]=2*a[i-2]+a[i-1]; 
	}

	while(~scanf("%d",&n))
	{
	   printf("%d\n",a[n]); 
	}
	return 0;
}

H:Small Water Problem

由于测试数据很小,直接迭代计算即可。

注意由于是四舍五入保留6位小数,所以我们得精确到第7位小数。

由于 float 的精度为 6~7 位,并且第 7 位小数也不是准确值,是由 8 位小数四舍五入的结果,如果使用会造成精度缺失。必须使用 double 来计算。

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    while(cin>>n){
        double x=sin(n);
        for(int i=1;i<=n;i++)
            x=sin(x);
        printf("%.6lf\n",x);
    }
    return 0;
}

I: RealBig Water Problem

其实开始只出了这一个题,但想了想,直接看到这么大的数据范围,人都会往找规律的地方想,于是在这题之前用一个数据范围小的sin,把他们往递归的方向带,笑~

 几次cos运算后会发现小数点后相同的位数增多,而保留的位数决定了在多少次cos运算后结果会相同.

 我们打一个表就可以发现在多少次后保留几位小数结果相同的情况,对大于它的直接输出,小于的可以迭代算或者打个表。

#include<bits/stdc++.h>
using namespace std;
int main(){
    char s[105];
    while(cin>>s){
        if(strlen(s)<3){
            int n=atoi(s);
            double x=cos(n);
            for(int i=1;i<=n;i++)
                x=cos(x);
            printf("%.6lf\n",x);
        }
        else
            printf("0.739085\n");
        memset(s,0,sizeof(s));
    }
    return 0;
}

J:this is the water-est problem

思路:简单的杨辉三角,打个表就行,实在不会复制粘贴也可以,(其实刚开始我是想打印30行的)


#include<iostream>
#include<cstdio>
int c[100][100];
int main(){
	//freopen("test.txt","r",stdin);
	//freopen("test.out","w",stdout);
	for(int i=0;i<20;i++){
		for(int j=0;j<=i;j++){
			if(j==0||j==i){
				c[i][j]=1;
			}
			else{
				c[i][j]=c[i-1][j-1]+c[i-1][j];
			}
			printf("%d ",c[i][j]);
		}
		printf("\n");
	}
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值