比赛链接:bistuacm 新生训练赛 第七场
难度:cf 900~1400
A
知识点:枚举
题意:寻找距离数组某个数最接近的a[i]<=k且b[i]=1的数。
解法:按题意模拟即可。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m,k;
cin>>n>>m>>k;
m--;
int a[222],b[222];
int i,t;
for(i=0;i<n;i++){
cin>>a[i];
}
for(t=0;;t++){
int x=m+t,y=m-t;
if(y>=0)if(a[y]&&a[y]<=k)break;
if(x<=n-1)if(a[x]&&a[x]<=k)break;
}
cout<<10*t;
}
B
知识点:数学
题意:找到大于a,且各数位只含一个非0数字的数,输出其和a的差。
解法:求出a的最高位和a的位数,(a的最高位+1)*10^(位数-1)即为所求数,求差即可。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m=1,k;
cin>>n;
k=n;
while(n>=10){
n/=10,m*=10;
}
if(k==n*m)cout<<m;
else cout<<(n+1)*m-k;
}
C
知识点:字符串
题意:一个字符串,若某字符不是最后一次出现,则需要占用一个空间。若出现了最后一次之后则释放空间。问至少需要多少空间。
解法:先预处理一遍每个字符出现的最后位置,然后按题意模拟即可。
#include<bits/stdc++.h>
using namespace std;
char a[1111111];
int main(){
int n,i,k;
int ma[26];
for(i=0;i<26;i++)ma[26]=0;
cin>>n>>k;
int m=0;
cin>>a;
for(i=0;a[i]!='\0';i++){
ma[a[i]-'A']=i;
}
int tong[26]={0},cnt=0;
for(i=0;a[i]!='\0';i++){
if(!tong[a[i]-'A'])tong[a[i]-'A']++,cnt++;
m=max(m,cnt);
if(tong[a[i]-'A']&&i==ma[a[i]-'A'])cnt--;
}
if(m>k)cout<<"YES";
else cout<<"NO";
}
D
知识点:博弈
题意:给定一数组。A每次可以取和为奇数的连续段,B每次可以取和为偶数的连续段。两人轮流取,先取不了的人输。问最优策略下谁赢。
解法:若sum为奇数,A直接获胜。
若sum为偶数,假设存在某奇数,显然A取完之后总和变成奇数,之后B无论取不取都是A获胜。
若不存在奇数,则A取不了,B获胜。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,i;
long long jud=0,sum=0;
cin>>n;
while(n--){
long long x;
cin>>x;
sum+=x;
if(x&1)jud=1;
}
if(sum&1)cout<<"First";
else if(!jud)cout<<"Second";
else cout<<"First";
}
E
知识点:贪心
题意:每一次可以进新房间或旧房间(要求是上一次走过的)。问房间最小值。
解法:显然不可能有两次上一次“同一时间”走到旧房间。因此遇到相同的数则新房间数加一即可。要注意的是t0为0的时候已经有一个房间,因此遇到0的时候一定有新房间。
#include<bits/stdc++.h>
using namespace std;
int a[222222];
int main(){
int n,i;
cin>>n;
for(i=0;i<n;i++)cin>>a[i];
sort(a,a+n);
int cnt=0;
for(i=0;i<n-1;i++)cnt+=a[i]==0?1:a[i]==a[i+1];
cout<<cnt+(!a[i]);
}
F
知识点:排序/map
题意:a数组有一些数。现给定两个数组b[m]和c[m],求某个i使b[i]在a中出现次数最多。若有多个最多的b[i],则需要让c[i]最多。
解法:用一个map存a中每个数出现的次数,然后可直接找出对应b[i]和c[i]在a中的出现次数。
#include<bits/stdc++.h>
using namespace std;
struct mov{
int b,c;
};
int a[222222];
mov m[222222];
map<int,int>M;
map<int,int>::iterator it1,it2;
bool f(int i,int j){
it1=M.find(m[i].b);
it2=M.find(m[j].b);
if(it1==M.end())return 1;
if(it2==M.end())return 0;
if(it1->second!=it2->second)return it1->second<it2->second;
else{
it1=M.find(m[i].c);
it2=M.find(m[j].c);
if(it1==M.end())return 1;
if(it2==M.end())return 0;
return it1->second<it2->second;
}
}
int main(){
int n,i;
cin>>n;
for(i=0;i<n;i++)cin>>a[i];
int t;
cin>>t;
for(i=0;i<t;i++)cin>>m[i].b;
for(i=0;i<t;i++)cin>>m[i].c;
sort(a,a+n);
int cnt=1,mm=1;
for(i=0;i<n-1;i++){
if(a[i]==a[i+1])cnt++;
else M[a[i]]=cnt,cnt=1;
}
M[a[i]]=cnt;
int m=0;
for(i=1;i<t;i++){
if(f(m,i))m=i;
}
cout<<m+1;
}