新生31场

立方和,对撞,差值求和(差分),最大与最小,哈夫曼编码,求素数Ⅰ

立方和:

题目描述

现给出一个三位数,先对这个三位数的各位数字的立方求和,然后再对求出的和中的各位数字的立方求和,如此一直继续下去,判断最后能否得到一个不再变化的固定值。如能得到一个固定值,就求出这个固定值;如果不能,则输出提示信息“error”。另外请注意,在求解过程中,若某一次求和过程中得到的值超过三位数,则只取后三位继续求立方和……
例如,对于三位数111,则第一次计算应是1×1×1+1×1×1+1×1×1=3,第二次计算应是0×0×0+0×0×0+3×3×3=27,第三次计算应是0×0×0+2×2×2+7×7×7=351,第四次计算应是3×3×3+5×5×5+1×1×1=153,第五次计算应是1×1×1+5×5×5+3×3×3=153,与第四次计算的结果相同,这时可不再计算,输出固定值153。
亲爱的同学,请你也来计算一下。

输入

输入只有一行,是一个三位数。

输出

输出也只有一行,如能得到一个固定值,则输出这个固定值;如不能,则输出一个提示信息“error”。

样例输入 Copy

111

样例输出 Copy

153
这个题我本来觉得过的几率不大,但一遍过了,好开心hhhh
复制代码
#include<iostream>
using namespace std;
int sum(int x)
{
    int a,b,c,X;
    a=x/100%10;
    b=x/10%10;
    c=x%10;
    X=a*a*a+b*b*b+c*c*c;
    return X;
}
int main(){
    int n,t,t1,x=0,m=10000;
    cin>>n;
    t=sum(n);
    while(m--)
    {
        t1=sum(t);
        if(t1==t)
        {
            x=1;
            break;
        }
        t=sum(t1);
    }
    if(x)
        cout<<t1<<endl;
    else
        cout<<"error"<<endl;
    return 0;
    
} 
复制代码

 对撞:

题目描述

小明发明了一个数字对撞机,两个位数相同的整数可以进行碰撞。碰撞过程中,将两个 整数的每一位进行比较,较小的那个数字会被撞得粉碎,较大的数字保留下来(如果两数 相同,都会保留)。例如下面例子中:
 
两个整数 13570 和 21673 碰撞后,对应数位上较小的值已经消失,碰撞的结果为:第一 个数字剩下 37,第二个数字剩下 2673。 
现在小明想让你写一个程序来显示数字碰撞机的结果,输入两个整数,输出碰撞后的两 个数字。(注意最终结果不能包含多余的前导 0)
 

输入

第一行一个整数 x,表示输入的第一个整数。 第二行一个整数 y,表示输入的第二个整数。

输出

输出包含两行,第一个表示 x 碰撞后的结果。 第二行表示 y 碰撞后的结果。 若 x 或者 y 所有数位上的数字都消失了,该行输出“BOOM”注意都是大写的。

样例输入 Copy

【样例1】
13570
21673
【样例2】
300
500
【样例3】
1234
5678

样例输出 Copy

【样例1】
37
2673
【样例2】
0
500
【样例3】
BOOM
5678

提示

样例2解释
300第一位被撞碎了,剩下00,因为不能包含前导0,输出0。500没有任何一位被撞碎。
样例3解释
1234每一位都被撞碎了,输出“BOOM”,5678没有任何一位被撞碎。
【数据范围】
对于50%的数据,0≤x,y<10^9
对于80%的数据,0≤x,y<10^100,即x,y的长度不超过100。
对于100%的数据,0≤x,y<=10^1000,即x,y的长度不超过1000。保证所有x和y的位数相同,且x,y本身没有多余的前导0
啊啊啊啊啊,这个题气死我了,修了接近一个小时的bug,结果是在一个很小的地方出的错,啊啊啊啊啊!!!
这个题是模拟,真的要把思路想清楚,对a和b分别判,要写两次(也还好啦),然后学会了一招,如何删除前导0
就是先判断根据循环如果不等于0的时候,标记一下。如果等于0看是否被标记,被标记的是合法的,正常输出就好啦。没被标记的就是前导0,忽略就OK.
复制代码
#include<iostream>
#include<cstring>
using namespace std;
char ch1[1000],ch2[1000];
int a[10000],b[10000];
int len1,len2;
int boom(int a[]){
    for(int i=0;i<len1;i++)
    {
        if(a[i]!=-1)
            return 0;
    }
    return 1;
}
int ju(int a[])
{
    for(int i=0;i<len1;i++)
    {
        if(a[i]!=0&&a[i]!=-1)
            return 0;
    }
    return 1;
}
int main(){
    int x=0;
    cin>>ch1>>ch2;
    len1=strlen(ch1);
    len2=strlen(ch2);
    for(int i=0;i<len1;i++)
        a[i]=ch1[i]-'0';
    for(int i=0;i<len2;i++)
        b[i]=ch2[i]-'0';
    for(int i=0;i<len1;i++)
    {
        if(a[i]>b[i])
            b[i]=-1;
        else if(a[i]<b[i])//
            a[i]=-1;
    }
    if(boom(a)==1)
        cout<<"BOOM"<<endl;
    else if(ju(a)==1)
        cout<<0<<endl;
    else
    {
        for(int i=0;i<len1;i++)
        {
            if(a[i]!=-1)
            {
                if(a[i]!=0)
                {
                    x=1;
                    cout<<a[i];
                }
                else
                {
                    if(a[i]==0&&x==1)
                    {
                        cout<<a[i];
                    }
                }
            }
        }
        cout<<endl;
    }
    x=0;
    if(boom(b)==1)
        cout<<"BOOM"<<endl;
    else if(ju(b)==1)
        cout<<0<<endl;
    else
    {
        for(int i=0;i<len1;i++)
        {
            if(b[i]!=-1)
            {
                if(b[i]!=0)
                {
                    x=1;
                    cout<<b[i];
                }
                else
                {
                    if(b[i]==0&&x==1)
                    {
                        cout<<b[i];
                    }
                }
            }
        }
        cout<<endl;
    }
    return 0;
}
复制代码

 差值求和:

题目描述

小明最近学习了差的绝对值,|a-b|表示a-b的绝对值,若a-b>=0,则|a-b|=a-b;若a-b<0,则|a-b|=-(a-b)。
经过几次练习,小明已经熟练掌握了差的绝对值,现在他找来了N个整数,开始任意取出两个数,求差的绝对值,再将所有差的绝对值相加。例如N=4,有4个整数,分别是1,2,3,4。任取两个数有6种取法,|1-2|=1,|1-3|=2,|1-4|=3,|2-3|=1,|2-4|=2,|3-4|=1,它们的和就是10。
由于运算量太大,累坏了小明。请你写一个程序帮他计算一下吧。
 

输入

第一行一个整数n,表示有n个整数
第二行n个整数,表示小明写下的n个整数
 

输出

输出一个数,表示任意两数差的绝对值之和。

样例输入 Copy

【样例1】
3
3 1 2
【样例2】
4
1 2 3 4

样例输出 Copy

【样例1】
4
【样例2】
10

提示

样例1解释:|3-1|=2,|3-2|=1,|1-2|=1,答案为4

对于40%的数据,n<=1000,0<=每个数<=1000
对于70%的数据,输入数据保证第二行的n个数字从小到大有序。
对于100%的数据,n<=100000,0<=每个数<=1,000,000,000
这个题我到现在还是迷迷糊糊的,没完全理解:
这个首先数据范围那么大,暴力首先pass,不可能的,能tl到怀疑人生,然后就想到用差分
因为自己不懂,在这里多说两句吧,助于自己理解;
序号 0 1 2 3 4 5 6 7
原数组 0 2 5 9 10 11 14 15
差分数组   2 3 4 1 1 3 1
这个就是差分数组,前缀和就是原数组
(注意一下序号!!这个很关键)
然后这个题要求所有任意两个数相减的绝对值,首先从小到大排序,就例如上面的这个数列;
2 5 9 10 11 14 15
14到15很友好,就是相差1;
11到15相差4,差分数组那得是11到14然后14到15,相差3+1
10到15以此类推,要经历中间那么多的加法
最后求的是那么多差值的总和,就是再找个变量ans相加算总和。
经过这么个模拟法,我好像又懂了一丝~~让我再悟一会~~~~先上ac代码:
复制代码
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e6+10;
int a[N],b[N];
int main(){
    long long int n,h=1,sum=0,ans=0,j=0;
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    sort(a+1,a+n+1);
    for(int i=2;i<=n;i++)
    {
        j++;
        b[j]=a[i]-a[i-1];
    }
    for(int i=j;i>=1;i--)
    {
        sum=sum+b[i]*h;
        ans=ans+sum;
        h++;
    }
    cout<<ans<<endl;
    return 0;
}
复制代码

这个代码细节很多,稍不在意就wa了,hhh,值得一品我觉得。可能还是我太菜,wuwuwu~

最大与最小:

题目描述

有一个只有加法和乘法的算术式,假设你可以合法的任意加括号,请求出这个算术式能得到的最大值和最小值。参与运算的数字都是正整数,数字个数不超过10。每个数字的大小不超过10。

输入

 一行,一个合法的算术式,两项项之间都有一个空格。

输出

两行,第一行为能得到的最大值,第二行为能得到的最小值。

样例输入 Copy

2 + 3 * 5 + 4 =

样例输出 Copy

45
21
这个不需要多说啥,代码直接能看懂,诶嘿
复制代码
#include<iostream>
using namespace std;
int main(){
    int a[100],b[100],n=1;
    char ch[100];
    cin>>a[n];
    b[n]=a[n];
    while(cin>>ch[n])
    {
        if(ch[n]=='=')
            break;
        n++;
        cin>>a[n];
        b[n]=a[n];
    }//到这一步都是读入的过程,方法很巧妙呀!! 
    for(int i=1;i<=n;i++)
    {
        if(ch[i]=='+')//求最大值,每个加法的部分加起来,最后再乘起来 
        {
            a[i+1]=a[i]+a[i+1];
            a[i]=1;
        }
        if(ch[i]=='*')//求最小值,这一步乘法该算就算 
        {
            b[i+1]=b[i]*b[i+1];
            b[i]=0;
        }
    }
    int sum=1;
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        sum=sum*a[i];//最大值是先算加法后算乘法 
        ans=ans+b[i];//最小值该怎么算怎么算 
    }
    cout<<sum<<endl;
    cout<<ans<<endl;
    return 0;
}
复制代码

哈夫曼编码:

题目描述

哈夫曼编码是一种编码方式,是可变字长编码的一种,由Huffman于1952年提出。该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫Huffman编码。简单地来说,就是出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的。
现在请你模拟这样的原则对给定的一个字符串进行字母统计。

输入

输入只有一行,是一个字符串,由小写英文字母组成,长度不超过255个字符。

输出

输出有若干行,每行有两部分组成:一个字母和该字母出现的频率,中间用一个空格分隔,并按频率高低排列,频率相同时则按字母的ASC码的先后顺序排列。

样例输入 Copy

soon

样例输出 Copy

o 2
n 1
s 1
这个题上来我知道用结构体做,奈何字符结构体用着用着用混了....
类推一下我发现了一个适用我自己的好方法
看最后的样例的结果,每一行就是变量数组a【】,里面的每一个位置分别是其中的成员函数
这题char和int,分别代表字母和出现的次数,行就是多组输入,一共26个字母,变量开到50就足够了
复制代码
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
struct mess{
    char id;
    int num;
}a[50];
int cmp(mess x,mess y)
{
    if(x.num==y.num)
        return x.id<y.id;
    else
        return x.num>y.num;
}
int main(){
    string ch;
    int len;
    cin>>ch;
    len=ch.size();
    for(int i=0;i<len;i++)
    {
        a[ch[i]-'a'].id=ch[i];
        a[ch[i]-'a'].num++;
    }
    sort(a,a+26,cmp);
    for(int i=0;i<len;i++)
    {
        if(a[i].num!=0)
            cout<<a[i].id<<" "<<a[i].num<<endl;
    }
    return 0;
}
复制代码

求素数Ⅰ:

题目描述

现给你N个0~9的数字并排成了一列,同时还给出了一个取数长度L。规定先从第1个数字开始从左往右连续取L个数字,拼成一个长度为L位(最高位为0的L-1位数除外)的数,然后从第2个数字开始从左往右连续取L个数字……,这样,最后最多可以得到N-L+1个L位数。现在请你将这些L位数中的素数按从小到大的顺序输出(如果产生重复,只需输出一个)。

输入

输入共有两行。
第一行为N和L,中间用空格隔开。(1≤N≤100,1≤L≤7)第二行为N个0~9的数字,中间用空格隔开。

输出

输出只有一行,含全部满足条件的素数,中间用逗号隔开。

样例输入 Copy

10 3
8 9 1 0 2 3 5 4 7 6

样例输出 Copy

547
这个题一直ac91,不知道哪出了问题,难受QAQ...
复制代码
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
typedef long long int ll;
ll a[N],b[N];
ll ss(ll x)
{
    if(x<2) return 0;
    for(int i=2;i<=x/i;i++)
        if(x%i==0)
            return 0;
    return 1; 
}
ll lenth(ll x)
{
    ll t=0;
    while(x>0)
    {
        x/=10;
        t++;
    }
    return t;
}
int main(){
    ll n,l;
    cin>>n>>l;
    for(ll i=0;i<n;i++)
        cin>>a[i];
    for(ll i=0;i<n-l+1;i++)
    {
        ll x=0;
        for(ll j=i;j<i+l;j++)
        {
            x=x*10+a[j];
        }
        b[i]=x;
    }
    sort(b,b+n-l+1);
    ll t=0;
    for(ll i=0;i<n-l+1;i++)
    {
        if(ss(b[i])&&lenth(b[i])==l)
        {
            if(t==0)
                printf("%lld",b[i]);
            else
                printf(",%lld",b[i]);
            t++;
        }
    }
    return 0;
}
复制代码

又不哭了,我又开心了,hhhh,题目说不能有重复的,然后用了vector去重了

复制代码
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int N=100010;
typedef long long int ll;
ll a[N],c[N];
ll ss(ll x)
{
    if(x<2) return 0;
    for(int i=2;i<=x/i;i++)
        if(x%i==0)
            return 0;
    return 1; 
}
ll lenth(ll x)
{
    ll t=0;
    while(x>0)
    {
        x/=10;
        t++;
    }
    return t;
}
vector<int> b;
int main(){
    ll n,l;
    cin>>n>>l;
    for(ll i=0;i<n;i++)
        cin>>a[i];
    for(ll i=0;i<n-l+1;i++)
    {
        ll x=0;
        for(ll j=i;j<i+l;j++)
        {
            x=x*10+a[j];
        }
        b.push_back(x);
    }
    sort(b.begin(),b.end());
    b.erase(unique(b.begin(),b.end()),b.end());
    ll t=0;
    for(ll i=0;i<b.size();i++)
    {
        if(ss(b[i])&&lenth(b[i])==l)
        {
            if(t==0)
                cout<<b[i];
            else
                cout<<","<<b[i];
            t++;
        }
    }
    return 0;
}
复制代码

这个是ac代码,嘻嘻嘻

posted @   小志61314  阅读(387)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
点击右上角即可分享
微信分享提示