vivo2020屆春季校園招聘在線編程考試 解題報告 Apare_xzc

vivo2020屆春季校園招聘在線編程考試 解題報告


題目鏈接:牛客鏈接


A. 手機屏幕解鎖模式

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

分析:

        這是一個智能手機的圖案鎖,有3*3=9個點。現在要求所有圖案中經過的點的個數再[m,n]這個範圍內的方案數。一個點也算作一種方案(和一般圖案鎖不太一樣)。
        我們可以大致計算一下總共方案的個數,大概是9!這麼多。當然,我們只是算了個大概,沒有考慮圖案的限制。這個大小遠遠小於10^8, 我們可以直接dfs所有方案。我們從9個點都出發一遍,每次在1-9之中都判斷一次,如果還沒走過,就可以考慮走到這個點。 我們一路dfs下去,如果遇到一個方案它的路徑長度(經過點的個數)在[m,n]範圍之內,我們就計數。如果路徑長度大於n, 我們就不必往下繼續搜索了。
        我們需要注意一個問題,就是如果路徑之中的前後兩個點A, C中間那個點B還沒有走過,我們就不能跨過這個點,不然A->B->C會被重複計數,因爲dfs(A)的時候已經去過B了。
        這題要求寫在測試類裏面,int solution(int m,int n)

代碼:

#include <bits/stdc++.h>
using namespace std;
void dfs(int m,int n,int x,int now,int &cnt,bool * vis,int * r) {
	if(x>n) return;
	r[x] = now;
	if(x>=m) {
		++cnt;
//		for(int i=1;i<=x;++i) cout<<r[i]<<" ";cout<<endl;
	}
	vis[now] = true;
	for(int to=0;to<9;++to) {
		if(vis[to]) continue;
		int px = now/3, py = now%3;
		int xx = to/3, yy = to%3;
		if(abs(px-xx)%2==0&&abs(py-yy)%2==0) {
			int mdx = (px+xx)/2, mdy = (py+yy)/2;
			int mid = mdx*3+mdy;
			if(vis[mid]) 
				dfs(m,n,x+1,to,cnt,vis,r);
		} 
		else 
			dfs(m,n,x+1,to,cnt,vis,r);
	}
	vis[now] = false;
}
int solution(int m,int n) {
	int cnt = 0;
	bool * vis = new bool[10];
	int * r = new int[10];
	for(int i=0;i<10;++i) vis[i] = false,r[i]=-1;
	for(int i=0;i<9;++i)
		dfs(m,n,1,i,cnt,vis,r);
	delete []vis;
	delete []r;
	return cnt;
}
int main(void) {
	int m,n;
	while(cin>>m>>n) {
		cout<<solution(m,n)<<endl;
	} 
	
	return 0;
} 

直接把dfs()和solution(int m,int n)兩個函數複製到class Solution()作爲成員函數即可。
在這裏插入圖片描述


B. 數位之積

在這裏插入圖片描述

分析:

         測試類要求的函數輸入的參數n和輸出的答案都是int。
        我們可以分析一下, 要求y的各個數位乘積等於n。我們把n分解質因數,得到n = P1^C1 * P2^C2 * P3^C3 * ... * Pk^Ck。 因爲十進制整數每個數位最大爲9,所以如果n存在大於9的質因數,我們便無法實現。所以,n只能包含2,3,5,7這4個質因數。
        如果n==0,則y最小爲10,如果1<=n<=9, 那麼y最小爲n+10,因爲題目要求y>9。
        處理完特殊的小數字後我們就可以開始討論一般的輸入。

  • 如果n的質因數存在大於7的,那麼n不可以被y的數位乘積表示,輸出-1
  • n最多隻含有上述的4個質因數,那麼我們就可以把n表示爲:n = 2^C2 * 3^C3 * 5^C5 * 7^C7。(C2,C3,C5,C7>=0)
  • 我們貪心地考慮,要使得y最小,首先要使y有最少的數位,其次在最少數位的基礎上,我們要使得y的字典序最小。
  • 首先,57必須一個佔一位,不然會超過9。我們先把2^3替換爲8,3^2替換爲9,這樣能有效減少數位。然後3可能剩下0或1個,2可能剩下0,1,2個。如果只剩下2,優先把2^2都替換爲4。如果有1個3,1個2,就替換爲6。如果有2個2一個3,就替換爲2,6。
  • 我們處理出2,3,4,5,6,7,8,9的個數後,就可以貪心地小數在前大數在後得到答案了。

代碼:

#include <bits/stdc++.h>
using namespace std;
int solution(int n) {
	if(n==0) return 10;
	if(n<=9) return 10+n;
	int c2 = 0, c3 = 0, c5 = 0, c7 = 0;
	while(n%2==0) c2++, n/=2;
	while(n%3==0) c3++, n/=3;
	while(n%5==0) c5++, n/=5;
	while(n%7==0) c7++, n/=7;
	if(n>1) return -1;  
	int c8 = 0, c9=0,c4=0,c6=0;
	c8 = c2/3; c2 %= 3;
	c9 = c3/2; c3 %= 2;
	if(c3==0) {
		c4 = c2/2; c2%=2;
	} else { //c3==1
		if(c2==1) c2=0,c3=0,c6=1;
		else if(c2==2) c2=1,c3=0,c6=1;
	}
	int ans = 0;
	while(c2--) ans = ans*10+2;
	while(c3--) ans = ans*10+3;
	while(c4--) ans = ans*10+4;
	while(c5--) ans = ans*10+5;
	while(c6--) ans = ans*10+6;
	while(c7--) ans = ans*10+7;
	while(c8--) ans = ans*10+8;
	while(c9--) ans = ans*10+9;
	if(ans<0) return -1;
	return ans;	
} 
int main(void) {
	int x;
	while(cin>>x) {
		cout<<solution(x)<<"\n";
	}
	
	return 0;
} 


C. vivo智能手機產能

時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 256M,其他語言512M

在vivo產線上,每位職工隨着對手機加工流程認識的熟悉和經驗的增加,日產量也會不斷攀升。
假設第一天量產1臺,接下來2天(即第二、三天)每天量產2件,接下來3天(即第四、五、六天)每天量產3件 … …
以此類推,請編程計算出第n天總共可以量產的手機數量。

分析:

        1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 6 6 6 6 6 6 7 7…
        二分找出最後一個連續的數字,然後求和即可。
        1^2 + 2^2 + 3^2 + ...+n^2 = n*(n+1)*(2n+1)/6

代碼:

#include <bits/stdc++.h>
using namespace std;
int solve(int n) {
	int left=0,right = 1000000;
	if(n<=1) return n;
	while(right-left>1) {
		int mid = (left+right)>>1;
		if(1ll*mid*(1+mid)/2>n) right = mid;
		else left = mid; //[)
	}
	int ans = 1ll*left*(left+1)*(2*left+1)/6;
	n -= (1+left)*left/2;
	ans += n*(left+1);
	return ans; 
} 
int main(void) {
	int x;
	while(cin>>x)
	{
		cout<<solve(x)<<"\n";
	}
	return 0;
} 

在這裏插入圖片描述


2020/4/10 12:33
xzc


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章