栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

13年12月CCF计算机软件能力认证

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

13年12月CCF计算机软件能力认证

总的来说第0次CCF认证的题目比较水 然而本菜鸡还是很多不会做
最大的收获是 T3 的单调栈

201312-1 出现次数最多的数

这道题太水了,当时提交后没存代码,这里复制的是闫老师的代码。

#include 
using namespace std;
const int N = 10010;
int n, s[N];

int main(){
    cin >> n;
    while (n--){
        int x;
        cin >> x;
        s[x] ++ ;
    }
    int res = 0;
    for (int i = 1; i < N; i ++ )
        if (s[i] > s[res]) res = i;
    cout << res << endl;
    return 0;
}
201312-2 ISBN号码

很水的模拟题(好像还是早年CSP普及组原题?),用python写的,也可用C++,直接放代码:

s = input()
s1 = s.replace('-', '')
sum = 0
for i in range(9):
    sum += int(s1[i]) * (i + 1)

sum = ('X' if sum % 11 == 10 else str(sum % 11))

if s1[-1] == sum:
    print('Right')
else:
    print(s[:-1], sum, sep='')
201312-3 最大的矩形

这道题目有的说了,菜鸡如我只会写暴力 O ( n 2 ) O(n^2) O(n2)做法,记得这个是单调栈经典题,但是想了很久也没想出来怎么套。一直希望能自己想出来所以迟迟没看题解 发现自己想多了 。
所以为了熟悉知识点,就先去做了洛谷的板子题:题目链接
之后就会做了,嗯。

先放暴力做法代码,思路是枚举每个矩形的高,然后找以此为矩形上底最远能到达的左右边界:

#include 
#include 
#include 
#include 
using namespace std;
const int maxn=1e4+5;

int n,a[maxn];

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	int ans=-1;
	for(int i=1;i<=n;i++){
		int l=i,r=i;
		while(a[l]>=a[i]&&l>=1) l--;
		while(a[r]>=a[i]&&r<=n) r++;
		ans=max(ans,(r-l-1)*a[i]);
	}
	printf("%dn",ans);
	return 0;
}

学了单调栈以后,就可以在 O ( n ) O(n) O(n)时间预处理好每个矩形的高对应的最远左右边界,具体是先用单调栈在 O ( n ) O(n) O(n)时间求出每个矩形左边第一个比自己矮的矩形的下标。同理求出右边第一个矮于自己的矩形下标。

最后再枚举每个矩形,通过左右边界和当前矩形高度求出面积,取最大值就是答案,也是 O ( n ) O(n) O(n)的。具体代码如下:

#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int maxn=1e5+5;

int n,h[maxn],l[maxn],r[maxn];
stack s;

int main()
{
	scanf("%d",&n);

	for(int i=1;i<=n;i++){
		scanf("%d",&h[i]);
		l[i]=0;
		r[i]=n+1;
	}
	s.push(1);
	for(int i=1;i<=n;i++){
		while(!s.empty() && h[s.top()]>h[i]){
			r[s.top()]=i;
			s.pop();
		}
		s.push(i);
	}
	while(!s.empty()) s.pop();
	s.push(n);
	for(int i=n;i>0;i--){
		while(!s.empty() && h[s.top()]>h[i]){
			l[s.top()]=i;
			s.pop();
		}
		s.push(i);
	}
	ll ans=0;
	for(int i=1;i<=n;i++){
		ans=max(ans, (ll)(r[i]-l[i]-1)*h[i]);
	}
	printf("%lldn",ans);		
	return 0;
}

这道题数据弱, O ( n 2 ) O(n^2) O(n2)的就可以过,所以这里放一个更强数据的 题目链接

201312-4 有趣的数

一道组合计数题(也有别的做法如:状态机DP、更简单的递推公式)
这里放个链接,可以看到 大佬们的花式题解

一开始公式推对了,但是没有写对。
具体是取模了但没完全取模导致爆 long long 了,所以以为是公式推错了,想了很久才检查出来。

我的做法:
对于要求3:最高位数字不为0,其实没必要考虑,因为2开头的满足要求的数与0开头的数之间存在一一对应(01和23之间的关系的对等的,对应变换 0 ↔ 2 , 1 ↔ 3 0 leftrightarrow 2, 1 leftrightarrow 3 0↔2,1↔3 仍热满足要求),所以只需要求出满足条件1和条件2的个数,再除以2就行。
具体01一共有 k k k 个( 2 ≤ k ≤ n − 2 2leq k leq n-2 2≤k≤n−2),剩下 n − k n-k n−k 个23。再分别确定01分界线和23分界线。
所以答案为: C n 2 × 1 × ( n − 3 ) + C n 3 × 2 × ( n − 4 ) + … + C n n − 2 × ( n − 3 ) × 1 C_n^2times 1 times (n-3) + C_n^3times 2 times (n-4)+ldots +C_n^{n-2}times (n-3) times 1 Cn2​×1×(n−3)+Cn3​×2×(n−4)+…+Cnn−2​×(n−3)×1.

代码见下:

#include 
#include 
using namespace std;
typedef long long ll;
const ll mod=1e9+7;

ll exgcd(ll a, ll b, ll& x, ll& y){ 
    if(!b) { x=1, y=0; return a; } 
	ll r=exgcd(b,a%b,y,x);
	y-=(a/b)*x;
    return r;
}

ll inv(ll x){
	ll u,v;
	exgcd(x,mod,u,v);
	return u%mod;
}

int main()
{
	ll n; 
	scanf("%lld",&n);
	ll ans=0,tmp=n;
	for(ll i=2;i<=n-2;i++){
		tmp=((tmp*inv(i)%mod) *(n-i+1))%mod;  // 注意溢出,要取2次模
		ans=(ans+tmp*(i-1)*(n-1-i))%mod;
	}
	ans=ans*inv(2)%mod;
	if(ans<0) ans+=mod;
	printf("%lldn",ans);	
	return 0;
}

BTW 据说第五次CSP 最佳文章 这道题必须用 状态机DP做

201312-5 I’m stuck!

DFS或BFS水题,效率最高的方法是分别从起点和终点DFS(或BFS),标记哪些方格可以走到,最后再扫一遍每个格子判断一下即可,复杂度是 O ( n ) O(n) O(n)的。
我写的是 O ( n 2 ) O(n^2) O(n2)的,数据比较小,也能过。
代码:

#include 
#include 
#include 
#include 
using namespace std;
typedef pair P;
const int maxn=55;

int R,C,sx,sy,ans;
char G[maxn][maxn];
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
vector

v; bool flag,vis[maxn][maxn]; void dfs(int x,int y,bool mode){ if(x<0||x>=R||y<0||y>=C||G[x][y]=='#'||vis[x][y]) return; vis[x][y]=1; if(mode) v.push_back(P(x,y)); if(G[x][y]=='+'||G[x][y]=='S'||G[x][y]=='T'){ if(G[x][y]=='T') flag=1; for(int i=0;i<4;i++){ int xx=x+dx[i],yy=y+dy[i]; dfs(xx,yy,mode); } } else if(G[x][y]=='-'){ dfs(x,y-1,mode); dfs(x,y+1,mode); } else if(G[x][y]=='|'){ dfs(x-1,y,mode); dfs(x+1,y,mode); } else if(G[x][y]=='.'){ dfs(x+1,y,mode); } return; } int main() { scanf("%d%d",&R,&C); for(int i=0;i for(int j=0;j scanf(" %c",&G[i][j]); if(G[i][j]=='S') sx=i,sy=j; } } dfs(sx,sy,1); if(!flag){ printf("I'm stuck!n"); exit(0); } for(auto p:v){ memset(vis,0,sizeof vis); flag=0; dfs(p.first,p.second,0); if(!flag) ans++; } printf("%dn",ans); return 0; }

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1011381.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号