1/3
[编程题]手机屏幕解锁模式
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 256M,其他语言512M
现有一个 3x3 规格的 Android 智能手机锁屏程序和两个正整数 m 和 n ,请计算出使用最少m 个键和最多 n个键可以解锁该屏幕的所有有效模式总数。
其中有效模式是指:
1、每个模式必须连接至少m个键和最多n个键;
2、所有的键都必须是不同的;
3、如果在模式中连接两个连续键的行通过任何其他键,则其他键必须在模式中选择,不允许跳过非选择键(如图);
4、顺序相关,单键有效(这里可能跟部分手机不同)。
输入:m,n
代表允许解锁的最少m个键和最多n个键
输出:
满足m和n个键数的所有有效模式的总数
输入例子1:
1,2
输出例子1:
65
例子说明1:
输入m=1,n=2,表示最少1个键,最多2个键,符合要求的键数是1个键和2个键,其中1个键的有效模式有9种,两个键的有效模式有56种,所以最终有效模式总数是9+56=65种,最终输出65。
class Solution {
public:
/**
* 实现方案
* @param m int整型 最少m个键
* @param n int整型 最多n个键
* @return int整型
*/
bool vis[10];
int ans[10];
bool Isbool(int now,int up){
int now_x = now%3;
if(now_x == 0) now_x = 3;
int now_y = ceil(now/3.0);
int up_x = up%3;
if(up_x == 0) up_x = 3;
int up_y = ceil(up/3.0);
// cout<<now_x<<" "<<now_y<<endl;
// cout<<up_x<<" "<<up_y<<endl;
if(now_x == up_x){
if(abs(now_y-up_y) == 1) return true;
else if(vis[3+now_x] == true) return true;
else return false;
}
if(now_y == up_y){
if(abs(now_x-up_x) == 1) return true;
else if(vis[2+(now_y-1)*3] == true) return true;
else return false;
}
if(abs(now_x - up_x) == abs(now_y - up_y)){
if(abs(now_x - up_x) == 1) return true;
else if(vis[5] == 1) return true;
else return false;
}
return true;
}
int dfs(int n,int up){
int cnt = 0;
if(n <= 0)
return 1;
for(int i = 1 ; i <= 9 ; i++){
if(vis[i] == true) continue;
if(up != 0)
if(Isbool(i,up) == false) continue;
vis[i] = true;
cnt += dfs(n-1,i);
vis[i] = false;
}
return cnt;
}
int solution(int m, int n) {
// write code here
memset(ans,0,sizeof(ans));
for(int i = 1 ; i <= 9 ; i++){
memset(vis,false,sizeof(vis));
ans[i] = dfs(i,0);
}
int cnt = 0;
for(int i = m ; i <= min(n,9) ; i++)
cnt += ans[i];
return cnt;
}
};
2/3
[编程题]数位之积
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 256M,其他语言512M
现给定任意正整数 n,请寻找并输出最小的正整数 m(m>9),使得 m 的各位(个位、十位、百位 ... ...)之乘积等于n,若不存在则输出 -1。
输入例子1:
36
输出例子1:
49
输入例子2:
100
输出例子2:
455
class Solution {
public:
/**
* 输入一个整形数值,返回一个整形值
* @param n int整型 n>9
* @return int整型
*/
int cnt[10];
int solution(int n) {
memset(cnt,0,sizeof(cnt));
for(int i = 9 ; i >= 2 ; i--){
int count = 0;
while(n%i == 0){
n/=i;
count++;
}
cnt[i] = count;
}
if(n != 1) return -1;
long long ans = 0;
for(int i = 2 ; i <= 9 ; i++){
for(int k = 1 ; k <= cnt[i] ; k++)
ans = ans*10+i;
}
return ans;
}
};
在vivo产线上,每位职工随着对手机加工流程认识的熟悉和经验的增加,日产量也会不断攀升。
假设第一天量产1台,接下来2天(即第二、三天)每天量产2件,接下来3天(即第四、五、六天)每天量产3件 ... ...
以此类推,请编程计算出第n天总共可以量产的手机数量。
class Solution {
public:
/**
*
* @param n int整型 第n天
* @return int整型
*/
int MAX = 300+50;
int cnt[350];
int sum[350];
int solution(int n) {
// write code here
cnt[0] = 0;
sum[0] = 0;
for(int i = 1 ; i < MAX ; i++){
cnt[i] = cnt[i-1]+i;
sum[i] = sum[i-1]+(cnt[i]-cnt[i-1])*i;
}
int l = 1 , r = MAX;
while(l<r){
int m =(l+r)>>1;
if(cnt[m] > n) r = m;
else l = m+1;
}
int ans = (l+r)>>1;
ans--;
return sum[ans]+(n-cnt[ans])*(ans+1);
}
};