CCF刷题总结——13年12月CCF计算机软件能力认证
2021-03-20
题意:简单题,统计出现次数最多的那个数,如果相等直接输出最小的即可。
思路:直接模拟即可
代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
map<int,int>mp;
for(int i=1;i<=n;i++) {
int x;
cin>>x;
mp[x]++;
}
int ans=0,idx=0;
for(auto item:mp) {
int x=item.first;
int y=item.second;
if(y>ans) ans=y,idx=x;
else if(y==ans) idx=min(idx,x);
}
cout<<idx<<'\n';
return 0;
}
题意:如题描述
思路:模拟即可
代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
string s;
cin>>s;
int len=s.size();
int k=1;
int ans=0;
for(int i=0;i<len-1;i++) {
if(s[i]>='0'&&s[i]<='9') {
ans=ans+k*(s[i]-'0');
k++;
// cout<<s[i]<<" "<<ans<<'\n';
}
}
ans%=11;
int f=1;
//cout<<ans<<'\n';
if(ans==10) {
if(s[len-1]!='X') f=0;
}
else {
if(ans!=(s[len-1]-'0')) f=0;
}
if(f) puts("Right");
else {
if(ans!=10)s[len-1]=ans+'0';
else s[len-1]='X';
cout<<s<<'\n';
}
return 0;
}
题意:找去一段连续区间能够组成的最大矩形面积
思路:经典单调栈思路。详情可以转移到另外一篇博客查看
注意:
初始化h[0],h[n+1]为-1,而tt栈顶每次维护一个单调栈即初始化为0,
因为条件为假如左边没有比起小的元素那么tt减到0,stk[0]=0,第一个元素已经初始化为0,肯定不会比当前元素大,所以其答案也正好为-1,即如果存在则答案为左边比起小的最大下标,不存在为-1
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int h[N];
int stk[N];
int l[N],r[N];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++) {
cin>>h[i];
}
h[0]=h[n+1]=-1;
int tt=0;
stk[0]=0;
for(int i=1;i<=n;i++) {
while(h[stk[tt]]>=h[i])tt--;
l[i]=stk[tt];
stk[++tt]=i;
}
tt=0;
stk[0]=n+1;
for(int i=n;i>=1;i--) {
while(h[stk[tt]]>=h[i]) tt--;
r[i]=stk[tt];
stk[++tt]=i;
}
int res=0;
for(int i=1;i<=n;i++) {
res=max(res,h[i]*(r[i]-l[i]-1));
}
cout<<res<<'\n';
return 0;
}
题意:如连接所示
思路:分类看待问题,将0,1看做一类,将2,3看做一类满足,0必在1前面,而2也必在3前面,对于其中的一类,假设0有k中取值,那么1则有n-k取值 同理2,3。预处理出组合数,求其从2到n-2的和即可,
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
const int mod=1e9+7;
typedef long long LL;
LL f[N][N];
void init()
{
for(int i=0;i<N;i++) {
for(int j=0;j<=i;j++){
if(!j)f[i][j]=1;
else f[i][j]=(f[i-1][j]+f[i-1][j-1])%mod;
}
}
}
int main()
{
init();
int n;
cin>>n;
LL ans=0;
for(int i=2;i<=n-2;i++) {
ans=(ans+1LL*(f[n-1][i]*(i-1)%mod*1LL*(n-i-1)%mod)%mod)%mod;
}
cout<<ans<<'\n';
return 0;
}
题意:走迷宫问题,要满足以下两个条件,其中第一个为从起始点出发能到达该点,并且从该点不能到达终点,问该种类型的点的个数。
思路:正向dfs1标记所有能够到达的点,反向dfs2标记掉能够从终点到达该点,如何通过反向边到达该点即满足,对上下左右四个方向编号,那么上下分别为0,2 即假设一个点(x1,y1)能够从上方到达(x2,y2),那么判断(x2,y2)能否通过下方到达(x1,y1)即可。注意图论中广泛存在反向边取的方法为对2进行异或,
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=55;
string mp[N];
bool st1[N][N],st2[N][N];
int r,c;
int dx[]={-1,0,1,0},dy[]={0,-1,0,1};
bool ok(int x,int y,int k){
if(mp[x][y]=='+') return true;
if(mp[x][y]=='S'||mp[x][y]=='T') return true;
if(mp[x][y]=='-'&&(k==1||k==3)) return true;
if(mp[x][y]=='|'&&(k==0||k==2)) return true;
if(mp[x][y]=='.'&&k==2) return true;
return false;
}
void dfs1(int x,int y)
{
st1[x][y]=true;
for(int i=0;i<4;i++){
int ex=x+dx[i];
int ey=y+dy[i];
if(ex<1||ex>r||ey<1||ey>c) continue;
if(mp[ex][ey]=='#'||st1[ex][ey]) continue;
if(ok(x,y,i)) dfs1(ex,ey);
}
}
void dfs2(int x,int y){
st2[x][y]=true;
for(int i=0;i<4;i++) {
int ex=x+dx[i];
int ey=y+dy[i];
if(ex<1||ex>r||ey<1||ey>c) continue;
if(mp[ex][ey]=='#'||st2[ex][ey]) continue;
if(ok(ex,ey,i^2)) dfs2(ex,ey);
}
}
int main()
{
cin>>r>>c;
for(int i=1;i<=r;i++) {
cin>>mp[i];
mp[i]=" "+mp[i];
}
int tx,ty;
for(int i=1;i<=r;i++){
for(int j=1;j<=c;j++){
if(mp[i][j]=='S') dfs1(i,j);
else if(mp[i][j]=='T'){
dfs2(i,j);
tx=i;
ty=j;
}
}
}
if(!st1[tx][ty]) return puts("I'm stuck!")*0;
int res=0;
for(int i=1;i<=r;i++){
for(int j=1;j<=c;j++) {
if(st1[i][j]&&!st2[i][j]) res++;
}
}
cout<<res<<'\n';
return 0;
}
标题:CCF刷题总结——13年12月CCF计算机软件能力认证
作者:xiaob0
地址:https://xiaobo.net.cn/articles/2021/03/20/1616246159373.html