2019天梯赛练习题(L1专项练习)

7-1 水仙花数 (20 分)

水仙花数是指一个N位正整数(N3),它的每个位上的数字的N次幂之和等于它本身。例如:1。 本题要求编写程序,计算所有N位水仙花数。

输入样例:

3

输出样例:

153
370
371
407

思路:遍历100-999,每次都按题意检测一下是否满足,满足则输出,但是这题坑点在不能直接用pow()函数,具体的可以百度pow()函数,主要是它调用的是double 类型参数,会导致精度转换的时候出现问题(个人编译是这样的,
输入3会少了153这个答案),自己手写一个power()函数就可以了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn=10005;
int power(int x,int y)
{
    int i=1,a=1;
    for(int i=0;i<y;i++)
        a=a*x;
    return a;
}
int main()
{
    int n;
    cin>>n;
    int l=power(10,n-1),r=power(10,n);
//    cout<<l<<" "<<r<<endl;
    for(int i=l;i<r;i++)
    {
        int t=i;
        int sum=0;
        while(t)
        {
            sum+=power(t%10,n);
            t/=10;
        }
        if(sum==i)
            cout<<i<<endl;
    }
    return 0;
}
7-2 找鞍点 (20 分)

一个矩阵元素的“鞍点”是指该位置上的元素值在该行上最大、在该列上最小。

本题要求编写程序,求一个给定的n阶方阵的鞍点。

输入样例1:

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

输出样例1:

2 1

输入样例2:

2
1 7
4 1

输出样例2:

NONE
思路:预处理出来每行的最大值,每列的最小值。然后遍历一遍,看两者是否同时满足就可以了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn=10005;
int n;
int a[maxn][maxn];
int maxx[maxn],minn[maxn];
bool flag1=true;
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
        cin>>a[i][j];
    for(int i=0;i<n;i++)
    {
        maxx[i]=a[i][0];
        minn[i]=a[0][i];
        for(int j=0;j<n;j++)
        {
            maxx[i]=max(maxx[i],a[i][j]);
            minn[i]=min(minn[i],a[j][i]);
        }
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            if(a[i][j]==maxx[i]&&a[i][j]==minn[j])
            {
                cout<<i<<" "<<j<<endl;
                flag1=false;
            }
        }
    }
    if(flag1)
        cout<<"NONE"<<endl;
    return 0;
}
7-3 黑洞数 (20 分)

黑洞数也称为陷阱数,又称“Kaprekar问题”,是一类具有奇特转换特性的数。

任何一个各位数字不全相同的三位数,经有限次“重排求差”操作,总会得到495。最后所得的495即为三位黑洞数。所谓“重排求差”操作即组成该数的数字重排后的最大数减去重排后的最小数。(6174为四位黑洞数。)

例如,对三位数207:

  • 第1次重排求差得:720 - 27 = 693;
  • 第2次重排求差得:963 - 369 = 594;
  • 第3次重排求差得:954 - 459 = 495;

以后会停留在495这一黑洞数。如果三位数的3个数字全相同,一次转换后即为0。

任意输入一个三位数,编程给出重排求差的过程。

输入样例:

123

输出样例:

1: 321 - 123 = 198
2: 981 - 189 = 792
3: 972 - 279 = 693
4: 963 - 369 = 594
5: 954 - 459 = 495

思路:将这位数,拆开放到数组再生成重排的最大的值和最小的值,然后循环知道n = 495,注意题意给了“如果三位数的3个数字全相同,一次转换后即为0。”,所以值为0的时候也要跳出来。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn=10;
int n;
int a[maxn];
int main()
{
    cin>>n;
    for(int t=1;;t++)
    {
        a[0]=n/100;a[1]=n/10%10;a[2]=n%10;
        sort(a,a+3);
        int maxx=a[2]*100+a[1]*10+a[0];
        int minn=a[0]*100+a[1]*10+a[2];
        n=maxx-minn;
        printf("%d: %d - %d = %d\n",t,maxx,minn,n);
        if(n==495 || n==0)
            break;
    }
    return 0;
}

7-4 简易连连看

本题要求实现一个简易连连看游戏模拟程序。

给定一个2的方阵网格游戏盘面,每个格子中放置一些符号。这些符号一定是成对出现的,同一个符号可能不止一对。程序读入玩家给出的一对位置(、(,判断这两个位置上的符号是否匹配。如果匹配成功,则将两个符号消为“*”并输出消去后的盘面;否则输出“Uh-oh”。若匹配错误达到3次,则输出“Game Over”并结束游戏。或者当全部符号匹配成功,则输出“Congratulations!”,然后结束游戏。

输入样例1:

2
I T I T
Y T I A
T A T Y
I K K T
11
1 1 1 3
4 2 4 3
3 1 4 2
2 2 1 2
3 1 2 4
4 4 3 1
2 1 3 4
3 3 1 4
4 1 2 3
2 4 3 2
1 1 2 2

输出样例1:

* T * T
Y T I A
T A T Y
I K K T
* T * T
Y T I A
T A T Y
I * * T
Uh-oh
* * * T
Y * I A
T A T Y
I * * T
Uh-oh
* * * T
Y * I A
* A T Y
I * * *
* * * T
* * I A
* A T *
I * * *
* * * *
* * I A
* A * *
I * * *
* * * *
* * * A
* A * *
* * * *
Congratulations!

输入样例2:

2
I T I T
Y T I A
T A T Y
I K K T
5
1 1 4 4
1 1 2 3
1 1 2 3
2 2 4 1
2 2 3 3

输出样例2:

Uh-oh
* T I T
Y T * A
T A T Y
I K K T
Uh-oh
Uh-oh
Game Over

题意:模拟即可,但注意这几个坑点,当全图不全为“*”时,选到了两个“*”也算错误;还有当已经全变好了,但是输入没结束是不用输出的。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn=105;
int n,m;
char a[maxn][maxn];
int x,y,xx,yy;
bool flag1=true;
int main()
{
    cin>>n;
    for(int i=1;i<=(2*n);i++)
    {
        for(int j=1;j<=(2*n);j++)
        {
            cin>>a[i][j];
        }
    }
    int t=2*n*2*n;
    cin>>m;
    int cnt=0;
    while(m--)
    {
        cin>>x>>y>>xx>>yy;
        if(cnt==3)
        {
            cout<<"Game Over"<<endl;
            break;
        }
        else
        {
            if(a[x][y]==a[xx][yy] && a[x][y]=='*')
            {
                bool flag2=true;
                for(int i=1;i<=(2*n);i++)
                {
                    for(int j=1;j<(2*n);j++)
                    {
                        if(a[i][j]!='*')
                    {
                        flag2=false;
                        break;
                    }
                }
                }
                if(!flag2)
                {
                    cnt++;
                    cout<<"Uh-oh"<<endl;
                }
            }
            else if(a[x][y]==a[xx][yy])
            {
                a[x][y]='*';
                a[xx][yy]='*';
//                t-=2;
//                if(!t)
                bool flag3=true;
                for(int i=1;i<=(2*n);i++)
                {
                    for(int j=1;j<(2*n);j++)
                    {
                        if(a[i][j]!='*')
                    {
                        flag3=false;
                        break;
                    }
                }
                }
                if(!flag3)
                {for(int i=1;i<=(2*n);i++)
                {
                    for(int j=1;j<(2*n);j++)
                    {
                        cout<<a[i][j]<<" ";
                    }
                    cout<<a[i][2*n]<<endl;
                }}
            }
            else
            {
                cnt++;
                cout<<"Uh-oh"<<endl;
            }
        }
    }
    for(int i=1;i<=(2*n);i++)
    {
        for(int j=1;j<(2*n);j++)
        {
            if(a[i][j]!='*')
            {
                flag1=false;
                break;
            }
        }
    }
    if(flag1)
        cout<<"Congratulations!"<<endl;
    return 0;
}
7-5 帅到没朋友 (20 分)

当芸芸众生忙着在朋友圈中发照片的时候,总有一些人因为太帅而没有朋友。本题就要求你找出那些帅到没有朋友的人。

输入样例1:

3
3 11111 22222 55555
2 33333 44444
4 55555 66666 99999 77777
8
55555 44444 10000 88888 22222 11111 23333 88888

输出样例1:

10000 88888 23333

输入样例2:

3
3 11111 22222 55555
2 33333 44444
4 55555 66666 99999 77777
4
55555 44444 22222 11111

输出样例2:

No one is handsome

思路:需要判断一下朋友圈只有一个人的时候,这个人是没有朋友的,要注意。不然的话就把好友都放到有一个set 里面,然后查询的时候就在set 里面看有没有,如果有的话,要把结果也放到一个set 判断是否是多次输出。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
const int maxn=10005;
int n,m;
set<int>s;
set<int>ans;
int main()
{
    scanf("%d",&n);
    while(n--)
    {
        scanf("%d",&m);
        int x;
        if(m>=2)
        {
            while(m--)
            {
                scanf("%d",&x);
                s.insert(x);
            }
        }
        else
            scanf("%d",&x);
    }
    scanf("%d",&m);
    int x;bool flag=false;
    int a[maxn];
    int i=0;
    while(m--)
    {
        scanf("%d",&x);
        if(s.count(x)==0)
        {
//            cout<<x<<endl;
            if(ans.count(x)==0)
                a[i++]=x;
            ans.insert(x);
            flag=true;
        }
    }
    if(!flag)
        printf("No one is handsome\n");
    else
    {
        for(int j=0;j<i-1;j++)
            printf("%05d ",a[j]);
        printf("%05d\n",a[i-1]);
    }
    return 0;
}
7-6 输出GPLT (20 分)

给定一个长度不超过10000的、仅由英文字母构成的字符串。请将字符重新调整顺序,按GPLTGPLT....这样的顺序输出,并忽略其它字符。当然,四种字符(不区分大小写)的个数不一定是一样多的,若某种字符已经输出完,则余下的字符仍按GPLT的顺序打印,直到所有字符都被输出。

输入样例:

pcTclnGloRgLrtLhgljkLhGFauPewSKgt

输出样例:

GPLTGPLTGLTGLGLL

思路:记录G,g,P,p,L,l,T,t的数量,然后循环输出即可。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
const int maxn=10005;
int n,m;
int main()
{
    string s;
    cin>>s;
    int len=s.length();
    int cnt1=0,cnt2=0,cnt3=0,cnt4=0;
    for(int i=0;i<len;i++)
    {
        if(s[i]=='G'||s[i]=='g')
            cnt1++;
        if(s[i]=='P'||s[i]=='p')
            cnt2++;
        if(s[i]=='L'||s[i]=='l')
            cnt3++;
        if(s[i]=='T'||s[i]=='t')
            cnt4++;
    }
    while(cnt1>0 || cnt2>0 || cnt3>0 ||cnt4>0)
    {
        if(cnt1>0)
        {
            printf("G");
            cnt1--;
        }
        if(cnt2>0)
        {
            printf("P");
            cnt2--;
        }
        if(cnt3>0)
        {
            printf("L");
            cnt3--;
        }
        if(cnt4>0)
        {
            printf("T");
            cnt4--;
        }
    }
    printf("\n");
    return 0;
}
7-7 A-B (20 分)

本题要求你计算AB。不过麻烦的是,A和B都是字符串 —— 即从字符串A中把字符串B所包含的字符全删掉,剩下的字符组成的就是字符串AB。

输入样例:

I love GPLT!  It's a fun game!
aeiou

输出样例:

I lv GPLT!  It's  fn gm!

思路:getline 读行,然后把要删去的字符用set存,遍历目标字符串,看是否在set里面出现过,出现过就输出“ ”,否则正常输出。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
const int maxn=10005;
int n,m;
string s1,s2;
set<char>s;
int main()
{
    getline(cin,s1);
    getline(cin,s2);
    int len=s2.length();
    for(int i=0;i<len;i++)
        s.insert(s2[i]);
    len=s1.length();
    for(int i=0;i<len;i++)
    {
        if(s.count(s1[i])==0)
            cout<<s1[i];
    }
    cout<<endl;
    return 0;
}

 

posted @ 2019-03-19 11:08  从让帝到the_rang  阅读(1776)  评论(0编辑  收藏  举报