2018網易內推筆試程式設計題(一)
萌新最近做了一下2018網易的內推程式設計題集合,要求3個小時解決八道程式設計題,本萌新兩個小時做了6道題,剩下兩道題直接放棄了,感覺難度不大,沒有具體涉及到什麼演算法,除了動態規劃。
下面對做題的思路以及過程做一個簡單的記錄:
1.彩色的磚塊:
一些彩色的磚塊。每種顏色由一個大寫字母表示。各個顏色磚塊看起來都完全一樣。現在有一個給定的字串s,s中每個字元代表小易的某個磚塊的顏色。小易想把他所有的磚塊排成一行。如果最多存在一對不同顏色的相鄰磚塊,那麼這行磚塊就很漂亮的。請你幫助小易計算有多少種方式將他所有磚塊排成漂亮的一行。(如果兩種方式所對應的磚塊顏色序列是相同的,那麼認為這兩種方式是一樣的。)
例如: s = “ABAB”,那麼小易有六種排列的結果:
“AABB”,”ABAB”,”ABBA”,”BAAB”,”BABA”,”BBAA”
其中只有”AABB”和”BBAA”滿足最多隻有一對不同顏色的相鄰磚塊。
輸入描述:
輸入包括一個字串s,字串s的長度length(1 ≤ length ≤ 50),s中的每一個字元都為一個大寫字母(A到Z)。
輸出描述:
輸出一個整數,表示小易可以有多少種方式。
解題思路:解題關鍵詞:最多存在一對不同顏色的相鄰磚塊;即分為兩種情況,(1)僅存在一對,那麼該字串僅有兩種字母,形似XXXYYYY(2)不存在。那麼就僅有一種字母
AC程式碼:
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
string str;
map<char, int> ss;
while(cin>>str){
for(int i = 0; i < str.length(); i++)
ss[str[i]]++;
if(ss.size()>2)
cout<<"0"<<endl;
else if(ss.size()==2)
cout<<"2"<<endl;
else
cout <<"1"<<endl;
}
}
2. 等差數列
如果一個數列S滿足對於所有的合法的i,都有S[i + 1] = S[i] + d, 這裡的d也可以是負數和零,我們就稱數列S為等差數列。
小易現在有一個長度為n的數列x,小易想把x變為一個等差數列。小易允許在數列上做交換任意兩個位置的數值的操作,並且交換操作允許交換多次。但是有些數列通過交換還是不能變成等差數列,小易需要判別一個數列是否能通過交換操作變成等差數列
輸入描述:
輸入包括兩行,第一行包含整數n(2 ≤ n ≤ 50),即數列的長度。
第二行n個元素x[i](0 ≤ x[i] ≤ 1000),即數列中的每個整數。
輸出描述:
如果可以變成等差數列輸出”Possible”,否則輸出”Impossible”。
解題思路:根據等差數列的性質,該數列必是有序的,要麼遞增要麼遞減,要麼就是常數列。對於此題,只需把數列排個序,相鄰元素做差,只要差不等,即Impossible。
AC程式碼:
#include<stdio.h>
#include<algorithm>
using namespace std;
#define N 50+5
int main()
{
int a[N],b[N],n;
while(scanf("%d",&n)!=EOF){
for(int i=0; i<n; i++)
scanf("%d",&a[i]);
sort(a,a+n);
for(int i=1;i<n;i++)
b[i-1] = a[i]-a[i-1];
bool flag;
flag = true;
for(int i=0 ;i<n-2; i++)
if(b[i+1] != b[i])
{
flag = false;
break;
}
if(flag)
printf("Possible");
else
printf("Impossible");
}
return 0;
}
3. 交錯01串
如果一個01串任意兩個相鄰位置的字元都是不一樣的,我們就叫這個01串為交錯01串。例如: “1”,”10101”,”0101010”都是交錯01串。
小易現在有一個01串s,小易想找出一個最長的連續子串,並且這個子串是一個交錯01串。小易需要你幫幫忙求出最長的這樣的子串的長度是多少。
輸入描述:
輸入包括字串s,s的長度length(1 ≤ length ≤ 50),字串中只包含’0’和’1’
輸出描述:
輸出一個整數,表示最長的滿足要求的子串長度。
解題思路:這題和“最大連續子串和”類似,只不過更簡單些。因為字串僅有01,因此只需把後一個字元與前一個字元比較,不同的話,計數器累加,相同的話,更新子串長度值,並置計數器為0,重新計數
AC程式碼:
#include<stdio.h>
#include<string>
#include<algorithm>
#include<iostream>
using namespace std;
#define Max 0xfffff
int main()
{
string str;
while(cin>>str){
int count=0,max_len = -Max;
for(int i=0; i<str.length();){
if(str[i+1] == str[i]){
if(count > max_len)
max_len = count;
count = 0;
}
else
count++;
i++;
}
if(count == str.length())
printf("%d",count);
else
printf("%d\n",max_len+1);
}
return 0;
}
4. 操作序列
小易有一個長度為n的整數序列,a_1,…,a_n。然後考慮在一個空序列b上進行n次以下操作:
1、將a_i放入b序列的末尾
2、逆置b序列
小易需要你計算輸出操作n次之後的b序列。
輸入描述:
輸入包括兩行,第一行包括一個整數n(2 ≤ n ≤ 2*10^5),即序列的長度。
第二行包括n個整數a_i(1 ≤ a_i ≤ 10^9),即序列a中的每個整數,以空格分割。
輸出描述:
在一行中輸出操作n次之後的b序列,以空格分割,行末無空格。
解題思路:此題序列的長度長達2*10^5,肯定不能直接模擬來的。我們可以先按照題目要求寫出前幾項:我們可以發現規律:b序列總是從最大的位置以2為差遞減到最小的位置,然後又以2為和遞增到第二大的位置,由此不難寫出AC程式碼
AC程式碼
#include<stdio.h>
#define N 200000+5
int a[N],b[N];
int main()
{
int n;
while(scanf("%d", &n) != EOF){
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
int num = 1;
for(int i=n; i>=1;){
b[num++] = a[i];
i -= 2;
}
int j;
if(n & 1) //分奇偶兩種情況
j = 2;
else
j = 1;
for( ; j < n; ){
b[num++] = a[j];
j += 2;
}
for(int k=1; k<=n; k++){
if(k != n)
printf("%d ",b[k]);
else
printf("%d\n",b[k]);
}
}
return 0;
}
5. 獨立的小易
小易為了向他的父母表現他已經長大獨立了,他決定搬出去自己居住一段時間。一個人生活增加了許多花費: 小易每天必須吃一個水果並且需要每天支付x元的房屋租金。當前小易手中已經有f個水果和d元錢,小易也能去商店購買一些水果,商店每個水果售賣p元。小易為了表現他獨立生活的能力,希望能獨立生活的時間越長越好,小易希望你來幫他計算一下他最多能獨立生活多少天。
輸入描述:
輸入包括一行,四個整數x, f, d, p(1 ≤ x,f,d,p ≤ 2 * 10^9),以空格分割
解題思路:此題是到簡單的數學題,我們要先判斷手中的d元錢夠不夠支付f天(每天一個蘋果嘛)的房租,不夠的話那就沒有繼續下去的必要了。k = d - f*x 。如果k<=0 那麼最大隻能活 min(f, d/x)天咯。k>0的話,那就用剩下的錢買蘋果交房租咯,即m*(p+x)=k,求m.
AC程式碼:
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
long long x, f, d, p;
while(cin>>x>>f>>d>>p){
int m,n=0,k;
k = d - x*f;
n = min(d/x, f);
if(k <= 0){
cout<< n <<endl;
}
else{
cout<< n+k/(p+x)<<endl;
}
}
return 0;
}