对于一个整数x,若x是11的倍数或x的数位(十进制)包含至少两个1,则x为完美数。
对于给定的数,如果是完美数则输出yes,否则输出no。
解法:按题意做即可。O(1)
给定一个长度为n(n<=2000)的数列a1,a2,...,an(ai={-1,+1}),求满足所有数乘积为正的子区间个数。
解法:设s[0]=1,令s[i]=(a1*a2*...*ai),则区间(i,j)的乘积为s[j]/s[i-1],枚举(i,j)并判断乘积是否为正即可。O(n^2)
n(n<=20)个数对,每个数对包含两个整数a,b(1<=a,b<=40),求最多能选取多少个数对,使得每个整数出现不超过一次。
解法:dfs枚举当前数对选或不选,同时用一个bool数组或者64位整数作为标记,如果选的话同时更新标记,并且维护当前选取数量的最大值作为答案。O(2^n)
#include
using namespace std;
int n,m;
const int N=25;
const int M=45;
int a[N],b[N],ans;
bool vis[M];
void dfs(int now,int sum){
if(sum>ans)
ans=sum;
if(now>n)
return;
if(!vis[a[now]]&&!vis[b[now]]){
vis[a[now]]=vis[b[now]]=1;
dfs(now+1,sum+1);
vis[a[now]]=vis[b[now]]=0;
}
dfs(now+1,sum);
}
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d %d",&a[i],&b[i]);
}
dfs(1,0);
printf("%d\n",ans);
return 0;
}
已知有n个位置(n<=10),给定一个序列a1,a2,...,am(m<=1e4,ai<=n),代表m个时刻,时刻i在位置ai有炸弹。初始角色在位置1,且保证时刻1的炸弹不在位置1。角色不能与炸弹在同一时刻出现在同一房间,可以通过在某个时刻结束时消耗1能量移动到任意其他房间。求最小消耗能量数。
解法:贪心。如果下一秒当前位置不是炸弹,那么没有消耗能量的必要;否则,需要消耗能量,那么就需要考虑让下一次消耗能量的时刻尽可能的晚。
例如n为4,m为6,序列 “2 1 3 2 1 4”,时刻1在位置1,在时刻2之前需要移动位置,显然移动到4是最优的,因为下一次需要消耗能量是在时刻5结束时。相应的,如果此时移动到3,则是时刻2结束时;如果移动到2,则是时刻3结束时。
令r[i][j]表示时刻i以后,位置j第一次出现的时刻,那么显然max{r[i][j]}(j从1到n)对应的j就是下一时刻角色所在位置为炸弹时需要移动到的位置。如果某个位置j在时刻i以后没有出现,则r[i][j]为m+1。
可以通过倒着做,维护上一次位置j出现的时刻,即可得到r[i][j]。
然后再正着做,模拟一遍移动过程即可得到答案。O(n*m)
#include
using namespace std;
int n,m,ans;
const int N=15;
const int M=10005;
int r[M],a[M],tt[N];
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++){
tt[i]=m+1;
}
for(int i=m;i>=1;i--){
r[i]=1;
for(int j=2;j<=n;j++){
if(tt[j]>tt[r[i]]){
r[i]=j;
}
}
tt[a[i]]=i;
}
int p=1;
for(int i=2;i<=m;i++){
if(a[i]==p){
ans++;
p=r[i-1];
}
}
printf("%d\n",ans);
return 0;
}
3个选择题,考察概念和模型细节。第一题是resnet,第二题是seq2seq模型,第三题是bagging和boosting。