[CSP冲刺班]CSP-J2011模拟赛#3

[CSP冲刺班]CSP-J2011模拟赛#3

诸题目君

1.面试

2.-Excel计数法

3.纸牌游戏

4.涨薪

5.富有数

T1-面试

原题传送门

题意:有n人参加面试,每人4轮,每轮有4个等级ABCD,如一轮及以上是D或两轮及以上是C,淘汰输出"failed",如三轮及以上是A,输出"sp offer",否则输出"offer".

思路:签到题。声明变量分别记录下A 、C 、D 的个数。具体见代码(太水了,dalao请自行跳过

#include<bits/stdc++.h>
using namespace std;
int t,c,a,d;
char s[5];
int main(){
	freopen("interview.in","r",stdin);
    freopen("interview.out","w"stdout);
	cin>>t;
	for(int i=1;i<=t;i++){
		cin>>s;
		c=0;a=0;d=0;
		for(int j=0;j<4;j++){
			if(s[j]=='D')d=1;
			if(s[j]=='C'){c++;}
			if(s[j]=='A'){a++;}
		}
		if(c>=2||d==1)cout<<"failed"<<endl;
		else if(a>=3)cout<<"sp offer"<<endl;
		else cout<<"offer"<<endl;
	}
	return 0;
}

天啊!如此简单的签到题,本蒟蒻只提了0pts!所以……

反思:你调试可以,但是!一定一定要删除调试代码!!!做题一定要细心,完事了更一定要认真检查,这种致命的低级错误绝对不能犯!!!



T2-Excel计数法

原题传送门

题意:给你一个数n,输出它在Excel中列的字母序号(如:6->F,27->AA以此类推)。

思路:进制转换。把他想成26进制,再转换计算。具体见代码(老简单了

#include<bits/stdc++.h>
using namespace stdl
string zm="ABCDEFGHIJKLMNOPQRSTUVWXYZ",s;
long long n;
int main(){
	cin>>n;
	for(;n>0;){
		n--;
		s=all[n%26]+s;
		n=(n-n%26)/26;
	}
	cout<<s<<endl;
}

反思:一开始我一脸茫然,打了个暴力计算每一个字母位,错了好多次,差点崩溃。到后来才想到把它打成进制转换,所以,做题(尤其考试),必须冷静思考!



T3-纸牌游戏

原题传送门

题意:n个人玩牌,每个人从min(剩余人数-1,a[i])个人中拿走一张牌,无牌者淘汰。问最后最少剩下多少人。

思路:贪心。在现存n个人的情况下, 对于第 i个人,如果a[i]<n−1 ,那么 第i个人必然会被淘汰出局,反之则永远不会被淘汰出局。

上代码:

#include<bits/stdc++.h>
using namespace std;
long long n,a[100100]
int main(){
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i]
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++){
		if(a[i]>=n-i){
			cout<<n-i+1<<endl;
			break; 
		}
	}
	return 0;
}

反思:原本我想不到其他方法,打了个暴力也没有写贪心。事实上,如果一道题想不出其他解法,除了拿部分分,观察数据范围,如果适合贪心,就试试。



T4-涨薪

原题传送门

题意:公司有n个员工,工资分别为a[1],a[2]…a[n]。每年有x个员工绩效A,工资3倍;有y个员工绩效B,工资2倍;其余C,工资不变。如果连续2年C,开除。问 m 年后公司需要发工资总和多少。

思路:贪心(这次题出的真阳间……这么多贪心)。a[1]——a[n],sort排序,从大到小分配从A到C的绩效,最后一个快速幂求解。具体见代码。

#include<bits/stdc++.h>
using namespace std;
#define 1000000007 mod
long long kuaisumi(long long k){
	long long p=m,ans=1;
	while(p){
		if(p&1)ans=(ans*k)%mod;
		k=(k*k)%mod;
		p>>=1;
	}
	return ans%mod;
}
bool cmp(int a,int b){return a>b;}
int main(){ 
	cin>>n>>m>>x>>y;
	for(int i=1;i<=n;i++)cin>>a[i];
	sort(a+1,a+1+n,cmp); 
	for(int i=1;i<=x;i++)sum+=((a[i]*kuaisumi(3)%mod)%mod);
    for(int i=x+1;i<=x+y;i++)sum+=((a[i]*kuaisumi(2)%mod)%mod);
	cout<<sum%mod<<endl;
	return 0;
}

反思:绝对不能在考试中偷懒,该优化的不优化,该剪枝的不剪枝,还想考满分?!想桃子(pich)!



T5-富有数

原题传送门

题意:n个数组成的序列,其中每一位都是6或8的数叫富有数,问这个序列中所有是富有序列的子序列的长度和。

思路:dp动规(把脑子倒空都想不到)。先去掉非富有数,再记录富有数个数,设 d p [ i ] [ j ] dp[i][j] dp[i][j] 表示前 i i i 种富有数里面选 j j j 个的方案数。
状态转移方程(参照君哥写一个):

  • 不 用 第 i 种 , d p [ i ] [ j ] = d p [ i − 1 ] [ j ] d p [ i ] [ j ] = d p [ i − 1 ] [ j ] ; 不用第 i 种,dp[i][j]=dp[i−1][j]dp[i][j]=dp[i−1][j]; idp[i][j]=dp[i1][j]dp[i][j]=dp[i1][j];

  • 用 第 i 种 , d p [ i ] [ j ] = d p [ i − 1 ] [ j − 1 ] ∗ t i d p [ i ] [ j ] = d p [ i − 1 ] [ j − 1 ] ∗ t i ; 用第 i 种,dp[i][j]=dp[i−1][j−1]∗tidp[i][j]=dp[i−1][j−1]∗ti; idp[i][j]=dp[i1][j1]tidp[i][j]=dp[i1][j1]ti;

  • d p [ i ] [ j ] = d p [ i − 1 ] [ j ] + d p [ i − 1 ] [ j − 1 ] ∗ t i dp[i][j]=dp[i−1][j]+dp[i−1][j−1]∗ti dp[i][j]=dp[i1][j]+dp[i1][j1]ti




MAP!!!

#include<bits/stdc++.h> 
#include <map>
using namespace std;
const int maxn = 1e6+10;
typedef long long LL;
LL a[maxn];
int n;

// map<key_type, value_type> name; 键是不能重复的,值可以重复  
map<long long, int> mp; // 定义一个键为long long类型,值为 int类型的map容器
map<long long, bool> v1;
map<string, int> v2;
map<pair<int, int>, vector<int>> v3; // 键必须要稳定状态的数据类型或者容器,不可修改

void count()
{
    for(int i=1; i<=n; i++) { // 键是富有数这个数字,值是这个富有数的个数 
        mp[a[i]]++; // 修改也是log的 
    }
} 

int main()
{
    scanf("%d", &n);
    for(int i=1; i<=n; ++i)
        scanf("%lld", &a[i]);
    count();
    printf("%d\n", mp[a[1]]); // mp[a[i]] 表示 a[i]为键对应的值 ,每次查找都是log(n)的 
    // 输出所有的a[i]与其对应的个数,遍历所有的键
    map<long long, int>::iterator i; // 定义一个名字为 i 的迭代器 
    for(i=mp.begin(); i!=mp.end(); ++i) { // 默认按照键升序来排序 
        printf("%lld  %d\n", i->first, i->second); / i表示一个键值对的指针 
    }
    return 0;
}

最后提醒

  • 比赛开数组的时候一定要计算使用的内存
  • 认真的研究每档部分分,在你想的满分做法不能保证是正解时,一定要写分段。 分段保平安!!!
  • map和离散化的代码要多看看,非常实用的知识点!!!
  • dp 设计的状态空间不够用,要想一想能不能滚动数组
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值