题目练一练

好久没发文章了,今天是五一假期的第一天,就劳动一下

废话不多说,直接进入主题

第1题     铅笔

桌面有n个盒子,第i个盒子有a[i]支铅笔。

你想要得到尽量多的铅笔,但是如果某两个盒子有相同数量的铅笔,那么你是不能同时拥有这两个盒子的。

问你最多可以得到多少支铅笔。

输入格式

第一行,一个整数n。 1<=n<=50。

第二行,n个整数,第i个整数是a[i]。 1<=a[i]<=10。

输出格式

一个整数。

输入/输出例子1

输入:

4

5 2 5 3

输出:

10

输入/输出例子2

输入:

3

5 5 5

输出:

5

这道题有两种做法;

第一种:先排序,再逐个和前面的数比较,若不相等就累加

这种方法比较简单,你们“勤奋”的小编就没打出来了

第二种:数组下标计数法,先用数组下标计数,然后从1~10逐个搜索,>0就累加下标

大家可以看一下代码

#include<bits/stdc++.h>
using namespace std;
int n,a[55],ans;
int main(){
    cin>>n;
    for (int i=1;i<=n;i++)
    {
        int x;
        cin>>x;
        a[x]++;
    }
    for (int i=1;i<=10;i++)
    {
        if (a[i]!=0) ans+=i;
    }
    cout<<ans;
    return 0;
}

很简洁,也很简单。

第2题     坐标统计

输入 个点在平面上的坐标(横纵坐标都是整数),对于每个点可以控制所有位于它左 下方的点(即横坐标 和纵坐标 都比它小),它可以控制的点的数目称为“战斗力”。依次 输出每个点的战斗力,最后输出战斗力最高的点的编号(如果若干个点的战斗力并列最高, 输出其中最大的编号)。

输入格式

第一行包含一个正整数 n,接下来的 行,每行描述一个点的坐标,第 i+1 行包含两个 正整数 和 y,表示编号为 的点的横坐标为 x,纵坐标为 y

输出格式

共有 n+1 行第 行到第 行,每行包含一个整数,第 行的整数表示编号为 的点的战 斗力,第 n+1 行表示战斗力最高的点的编号。

输入/输出例子1

输入:

6

4 2

6 6

4 8

15 6

11 9

8 14

输出:

0

1

0

1

3

3

6

样例解释

1<=n<=100,1<=x<=1000,1<=y<=1000

这道题也很简单,主要是n只有100,正常搜索就行了

#include<bits/stdc++.h>
using namespace std;
int n,k,maxx=1,x[105],y[105],s[105];
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>x[i]>>y[i];
    for(int i=1;i<=n;i++)
    {
    	k=0;
		for(int j=1;j<=n;j++)
    	{
    		if(x[j]<x[i]&&y[j]<y[i]) k++;
		}
		s[i]=k;
        cout<<s[i]<<'\n';
		if (s[i]>=s[maxx]) maxx=i;
	}
	cout<<maxx;
	return 0;
}

主要注意的是if (s[i]>=s[maxx])这里的>=,而不是>,其它就没有难度了

第三题   卡片

有n张卡片从左往右排成一行,一开始每张卡片都是空白,依次进行如下三个步骤:

(一)小A同学给每个卡片都写上一个数字,每个数字都是0至9内的数字,小A保证至少有一张卡片的数字不是0。

(二)小B同学把n张卡片的次序打乱,记这n张卡片的数字从左往右串起来形成一个整数X。小B保证X不会有前导零。

(三)小C同学把n张卡片的次序打乱,记这n张卡片的数字从左往右串起来形成一个整数Y。小C保证Y不会有前导零。

问题是:X与Y的差的绝对值最大可以是多少?输出该最大值。

输入格式

一个整数n1<=n<=17

输出格式

一个整数。

输入/输出例子1

输入:

2

输出:

72

输入/输出例子2

输入:

17

输出:

89999999000000001

样例解释

这道题主要是找规律,找到规律以后就很容易做了,规律在代码里面已经有了,这里就不多说。

#include<bits/stdc++.h>
using namespace std;
long long n,x,y,z,xx,yy,a[15];
int main(){
    scanf ("%lld",&n);
    a[1]=1;
    a[0]=(n-1)/2;
    a[9]=(n-1)/2+(n-1)%2;
    for (int i=9;i>=0;i--)
    	for (int j=1;j<=a[i];j++)
    		x=x*10+i;
    for (int i=1;i<10;i++)
    {
		int k=i;
		if (i==2) k=0;
    	for (int j=1;j<=a[k];j++)
    		y=y*10+k;
	}
	printf ("%lld",x-y);
    return 0;
}

第4题     相同

如果x是y的约数,且x>1与x<y同时成立,那么x就是y的“真约数”。

有n个整数,第i个整数是a[i]。每一次使用魔法,你可以随意的选择a数组的某一个数,然后把该数变成它的“真约数”。

你可以使用无数次魔法,也可以不使用魔法。你的目标是使得a数组的每一个数都相同。

如果可以完成任务输出"yes",否则输出"no"。

输入格式

多组测试数据。

第一行,一个整数G,表示有G组测试数据。1<=G<=5。

每组测试数据格式如下:

第一行,一个整数n。 1<=n<=50。

第二行,第i个整数是a[i]。 1<=a[i]<=1000000000。

输出格式

G行,每行一个字符串, "yes"或者"no",双引号不用输出。

输入/输出例子1

输入:

5

2

2 4

3

3 6 7

4

516489004 351371688 811236122 359319772

10

774790715 541447280 142096365 445121785 583653195 71374815 798454490 409670625 942953335 8997395

3

1 1 1

输出:

yes

no

yes

yes

yes

样例解释

这道题看似很难,实际上很难

题目中已经告诉了我们这道题做题的思路,再加以思考,就很容易了

#include<bits/stdc++.h>
using namespace std;
long long g,n,a[55],k;
int main(){
    scanf ("%lld",&g);
    while (g--)
    {
    	scanf ("%lld",&n);
    	for (int i=1;i<=n;i++)
            scanf("%lld",&a[i]);
        int f=0;
        for (int i=2;i<=n;i++)
            if (a[i]!=a[i-1])
                f=1;
        k=a[1];
    	for (int i=2;i<=n;i++)
    		k=__gcd(k,a[i]);
		if (k>1||f==0) printf ("yes\n");
        else printf("no\n");
	}
    return 0;
}

其实就是最大公约数的问题

第5题     魔力柱子

魔法宫殿里有n条柱子.第i条柱子的高度是hi。魔法师会对柱子施法:把所有高于高度H的柱子“削平”到高度H,这样一次施法消耗的魔力值是从所有柱子移除的1×1方块的总和。为了不要让魔法师太累,一次施法消耗的魔力值要小于等于限定值k,(k≥n),那么最少需要多少次施法,才能使得所有柱子的高度都变成相同?

下面图可以参考(样例1 ) :

输入格式

输入第-行是两个整数n和k, 表示柱子的数量和施法的限定值k。

第二行有n个空格隔开的整数h1,h2,…hn

输出格式

输出只有一个整数,表示最少需要的施法数,使得每条柱的高度都相同。

输入/输出例子1

输入:

5 5

3 1 2 2 4

输出:

2

输入/输出例子2

输入:

4 5

2 3 4 5

输出:

2

样例解释

样例如图所示,需要2次施法,第1次设定H为2,消耗魔力值为3,第2次设定H为1,消耗魔力值为4。

对于50%的数据,1≤n≤2000,hi≤2000。

对于100%的数据,1≤n≤2×10^5,n≤k≤10^9,hi≤2×10^5

这道题的难度很高(超时),但是只要抓住关键,就能解决了,代码比较精简

#include<bits/stdc++.h>
using namespace std;
int n,k,a[200005],js,ans=1;
int main(){
    cin>>n>>k;
    for (int i=0;i<n;i++)
    {
        int t;
        cin>>t;
        a[t]++;
    }
    for (int i=200000;i>=1;i--)
    {
        a[i]+=a[i+1];
        if (a[i]==n) break;
        if (js+a[i]<=k) js+=a[i];
        else
        {
            js=a[i];
            ans++;
        }
    }
    cout<<ans;
    return 0;
}

还是非常值得思考及练习的。

谢谢您的观看,如果您还满意的话,请留下您的点赞、收藏以及您的好评哦

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值