洛谷练题4

1·小鱼比可爱

题目描述

人比人,气死人;鱼比鱼,难死鱼。小鱼最近参加了一个“比可爱”比赛,比的是每只鱼的可爱程度。参赛的鱼被从左到右排成一排,头都朝向左边,然后每只鱼会得到一个整数数值,表示这只鱼的可爱程度,很显然整数越大,表示这只鱼越可爱,而且任意两只鱼的可爱程度可能一样。由于所有的鱼头都朝向左边,所以每只鱼只能看见在它左边的鱼的可爱程度,它们心里都在计算,在自己的眼力范围内有多少只鱼不如自己可爱呢。请你帮这些可爱但是鱼脑不够用的小鱼们计算一下。

输入格式

第一行输入一个正整数 ,表示鱼的数目。

第二行内输入 个正整数,用空格间隔,依次表示从左到右每只小鱼的可爱程度 。

输出格式

一行,输出 个整数,用空格间隔,依次表示每只小鱼眼中有多少只鱼不如自己可爱。

样例 #1

样例输入 #1

6
4 3 0 5 1 2

样例输出 #1

0 0 0 3 1 2

提示

对于 的数据,,。

我的题解:

#include<iostream>

using namespace std;

int main(){

int n,a[10000],b[10000];

cin>>n;

for(int i=1;i<=n;i++){

cin>>a[i];

}

for (int i=1;i<=n;i++)

for (int j=i;j>=1;j--)

{

if (a[j]<a[i])

b[i]++;

}

for (int i=1;i<=n;i++) cout<<b[i]<<" ";

return 0;

}

2·[NOIP2015 普及组] 金币

题目背景

NOIP2015 普及组 T1

题目描述

国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十天),每天收到四枚金币……;这种工资发放模式会一直这样延续下去:当连续 天每天收到 枚金币后,骑士会在之后的连续 天里,每天收到 枚金币。

请计算在前 天里,骑士一共获得了多少金币。

输入格式

一个正整数 ,表示发放金币的天数。

输出格式

一个正整数,即骑士收到的金币数。

样例 #1

样例输入 #1

6

样例输出 #1

14

样例 #2

样例输入 #2

1000

样例输出 #2

29820

提示

【样例 1 说明】

骑士第一天收到一枚金币;第二天和第三天,每天收到两枚金币;第四、五、六天,每天收到三枚金币。因此一共收到 枚金币。

对于 的数据,。

我的题解:

#include<iostream>

using namespace std;

int main(){

int day,sum=0,a,b;

cin>>day;

a=1;

b=1;

for(int i=1;i<=day;i++)

{

sum=sum+a;

b--;

if(b==0)

{

a++;

b=a;

}

}

cout<<sum;

return 0;

}

转发其它代码:

1·#include<iostream>

using namespace std;

int main()

{

int a,b=0,c=1,i;//a为天数,b为金币,c为每天比原来每天多获得的金币数

cin>>a;

for(i=1;i<=a;i++)

a-=i,b+=c*c,c++;//金币每天加上c的2次方,天数当然要减i了

cout<<b+a*c;//最后算上剩余的a乘加的最多一次的c

return 0;

}

2·#include <bits/stdc++.h>

using namespace std;

int main()

{

int k,coins = 0,days=0;

cin >>k;

for(int i = 1;i <= k;i++) {

for(int j = 1;j <= i;j++)

{

coins += i;// i 代表行数,同时也是当天可得的金币数

days++;

if ( days == k)//天数达到了指定的天数

break;

}

//结束外层循环

if ( days == k) {

//天数达到了指定的天数

break;

}

}

cout<<coins;

return 0;

}

3.【深基4.例11】数列求和

题目描述

计算 的值,其中正整数 不大于 100。由于你没有高斯聪明,所以你不被允许使用等差数列求和公式直接求出答案。

输入格式

输入一个正整数 ​。

输出格式

输出一个正整数,表示最后求和的答案。

样例 #1

样例输入 #1

100

样例输出 #1

5050

提示

数据保证,。

我的代码:

#include<iostream>

using namespace std;

int main(){

int n,sum;

cin>>n;

for(int i=1;i<=n;i++)

{

sum=sum+i;

}

cout<<sum;

return 0;

}

*4.【深基4.例13】质数口袋

题目描述

小 A 有一个质数口袋,里面可以装各个质数。他从 开始,依次判断各个自然数是不是质数,如果是质数就会把这个数字装入口袋。口袋的负载量就是口袋里的所有数字之和。但是口袋的承重量有限,不能装得下总和超过 的质数。给出 ,请问口袋里能装下几个质数?将这些质数从小往大输出,然后输出最多能装下的质数个数,所有数字之间有一空行。

输入格式

一行一个正整数 。

输出格式

将这些质数从小往大输出,然后输出最多能装下的质数个数,所有数字之间有一空行。

样例 #1

样例输入 #1

100

样例输出 #1

2
3
5
7
11
13
17
19
23
9

提示

数据保证,​。

如何找质数?

1·最暴力也是最直观的方法——枚举法。明显看出100以内的质数有:2,3,5,7,11,13,17,19,23,29,31,27,41,43,47,53,59,61,67,71,73,79,83,89,97。但对于此题而言,明显还不够。。。而且,一一赋值比较也不可取。

2·寻找了一遍求质数的方法以后,发现判断质数的函数:当一个数的因数中(除了1)没有小于等于这个数的算数平方根的时,这个数便是质数

结合一些大佬的算法,摸索了一下

#include<iostream>

using namespace std;

long long top,a[100050],n,s;

bool prime(int x)

{

if(x<2) return 0;

if(x==2) return 1;

for(int i=2;i<=sqrt(x);i++)

if(x%i==0) return 0;

return 1;

}

int main()

{

cin>>n;

for(int i=2;i<=100000;i++)

{

if(prime(i)==1)

{

a[++top]=i;

}

}

int zs=0;

for(int i=1;i<=top;i++)

{

if(s+a[i]>n)

break;

s+=a[i];

zs++;

}

for(int i=1;i<=zs;i++)

{

cout<<a[i]<<endl;

}

cout<<zs;

}

 

 

标识不出来!!!!

哦哦哦,头文件的问题!!!

#include<bits/stdc++.h>

using namespace std;

long long top,a[100050],n,s;

bool prime(int x)

{

if(x<2) return 0;

if(x==2) return 1;

for(int i=2;i<=sqrt(x);i++)

if(x%i==0) return 0;

return 1;

}

int main()

{

cin>>n;

for(int i=2;i<=100000;i++)

{

if(prime(i)==1)

{

a[++top]=i;

}

}

int zs=0;

for(int i=1;i<=top;i++)

{

if(s+a[i]>n)

break;

s+=a[i];

zs++;

}

for(int i=1;i<=zs;i++)

{

cout<<a[i]<<endl;

}

cout<<zs;

}

 

大佬的题解

1.题意

给定范围,求该范围内从小到大质数和亦不超过此范围的所有质数及其个数。

2.思路

在这里的正解应该是欧拉筛。欧拉筛是埃特里尼质数筛法的升级版,即避免了所有重复操作,并使时间复杂度达到了O(n)O(n)。至于具体讲解,请看模板】线性筛素数 题解(侵权删),他们比我讲的好。

当然,此题还需要使用前缀和的思想,即用cnt[i]cnt[i]表示第11到第ii个数的和。所以我们可以利用此方法存质数的前缀和并判断输出即可。

3.代码

  #include<bits/stdc++.h>
 #define maxn 100001
using namespace std;
int isprime[100001],prime[100001],cnt[100001],m;
inline int get_list(){register int tot=0;
    for(register int i=2;i<=maxn;i++){
        if(!isprime[i])prime[++tot]=i,cnt[tot]=cnt[tot-1]+i;//存质数并处理前缀和 
        for(register int j=1;j<=tot&&i*prime[j]<=maxn/*此处可修改并加快时间*/;j++){
            isprime[i*prime[j]]=1;//处理质数表 
            if(i%prime[j]==0)break;//退出判断,因为下一个一定被筛过 
        }
    }
    return tot;//返回质数个数 
}
int main(){
    std::cin>>m;//输入 
    int ans=get_list(),/*生成表*/ans_final;
    for(int i=1;i<=ans;++i){
        if(cnt[i]>m)break;//退出 
        cout<<prime[i]<<'\n';
        ans_final=i;//存答案 
    }
    cout<<ans_final;//输出 
    return 0;
}

**存疑:什么是欧拉筛和艾特里尼质数筛法?没有学过,无法理解,还需寻找资料充实**

 

#include <bits/stdc++.h>
using namespace std;

namespace IO { //快读快输板子
    #pragma GCC target("avx")
    #pragma GCC optimize("Og")
    #pragma GCC optimize("Ofast")
    
    template<class T>
    inline void read(T& x) {
        x = 0;
        char ch = getchar();
        while(ch < '0' || ch > '9') {
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9') {
            x = x * 10 + ch - '0';
            ch = getchar();
        }
    }
    
    template<class T>
    inline void write(const T& x) {
        if(x > 9) write(x / 10);
        putchar(x % 10 + '0');
    }
};

using namespace IO;

int L,cnt;

bool isprime(int x) { //判断素数
    if(x == 2 || x == 3) return 1;
    if(x < 2) return 0;
    if(x % 6 != 1 && x % 6 != 5) return 0;
    for(int i = 5;i*i <= x;i += 6) {
        if(x % i == 0 || x % (i + 2) == 0) return 0;
    }
    return 1;
}

int main() {
    read(L);
    for(int i = 2;i <= L;i++) {
        if(L - i < 0) {
            break;
        }
        if(isprime(i) && L - i >= 0) {
            L -= i;
            write(i);puts("");
            ++cnt;
        }
    }
    write(cnt);puts(""); 
    return 0;
}

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Williamtym

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值