2019天梯賽練習題(L1專項練習)
水仙花數是指一個N位正整數(N≥3),它的每個位上的數字的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 分)
本題要求你計算A−B。不過麻煩的是,A和B都是字符串 —— 即從字符串A中把字符串B所包含的字符全刪掉,剩下的字符組成的就是字符串A−B。
輸入樣例:
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;
}
2019天梯賽練習題(L1專項練習)