申明:大概题意是从牛客网讨论区嫖的,题目的输入、输出以及数据数据范围也有些不知,大家看看思路就好,这些细节就不管了QAQ。有错欢迎纠正~
阿里笔试3.20
题目一(暴搜)
扑克牌1-10,各4张,共40张。随便抽一些,一个10个数字的数组 1 1 1 2 2 2 2 2 1 1 ,表示每个牌的数目,可以五张顺子,可以三个对组成连队,可以一个对,可以单张,问最少多少次可以出完牌。
思路:暴搜
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 510;
int a[12];
int ans;
void dfs(int cur) {
if(cur >= ans) return;
bool flag = 0;
for(int i = 1;i <= 10;++i)
if(a[i]) {
flag = 1;break;
}
if(!flag) {
ans = cur;return;
}
for(int i = 1;i <= 6;++i) {//顺子
if(a[i]&&a[i+1]&&a[i+2]&&a[i+3]&&a[i+4]) {
for(int j = i;j <= i+4;++j)
a[j]--;
dfs(cur+1);
for(int j = i;j <= i+4;++j)
a[j]++;
}
}
for(int i = 1;i <= 8;++i) {//连对
if(a[i]>1&&a[i+1]>1&&a[i+2]>1) {
for(int j = i;j <= i+2;++j)
a[j] -= 2;
dfs(cur+1);
for(int j = i;j <= i+2;++j)
a[j] += 2;
}
}
for(int i = 1;i <= 10;++i)
cur += (a[i]+1)/2;
if(ans > cur) ans = cur;
}
int main() {
for(int i = 1;i <= 10;++i) {
scanf("%d",&a[i]);
}
ans = 40;
dfs(0);
printf("%d\n",ans);
}
/*
1 1 1 2 2 2 2 2 1 1
*/
题目二(dp)
一堆各自非递减的字串,能组成的最长非递减字串的长度。字符串由小写字母组成。
思路:dp,用
表示以字符
结尾的最长字符串,需要先排序。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 100010;
int n;
int dp[27];
char str[maxn];
struct node {
int s,e;
int len;
bool operator <(const node &b) {
if(e == b.e) return s<b.s;
return e<b.e;
}
}a[maxn];
int main() {
scanf("%d",&n);
for(int i = 0;i < n;++i) {
scanf("%s",str);
a[i].s = str[0]-'a';
a[i].len = strlen(str);
a[i].e = str[a[i].len-1]-'a';
}
sort(a,a+n);
for(int i = 0;i < n;++i) {
int res = dp[a[i].e];
for(int j = 0;j <= a[i].s;++j) {
res = max(res,dp[j]+a[i].len);
}
dp[a[i].e] = res;
}
int ans = 0;
for(int i = 0;i < 26;++i) {
ans = max(ans,dp[i]);
}
printf("%d\n",ans);
}
/*
4
aaa
bcd
bcdef
zzz
*/