c++寒假班错题分析 (2.2)

这次就不弄错题列表了这次分析的有 贪心纪念评分组最长公共子序列,拓展一下 奖学金。

奖学金

先看一下奖学金吧(这段有点难,做好心理准备):

c++寒假班错题分析 (2.2)_第1张图片

c++寒假班错题分析 (2.2)_第2张图片

 这个题意思没什么问题吧,就是给你一堆数据,按他的要求排序后输出。

这个题目有很多种解法。

1.可以结构体外面写一个cmp函数。

大家应该都会。

2.也可以在sort函数中写一个比较规则。

也不难,就不讲了。

主要讲的是使用opertor(重载运算符)。简单给大家介绍一下,如果还不懂可以去OI WIKI。书归正传,operator就是把函数换成自己的规则,比如哪个有病的,把<,换成>也可以。

注意:operator是个函数

要这样定:

 bool operator< (const int &a)const{
    return ...;
}

你可以理解为operator< 是个函数名,这里的operator后面这能跟逻辑运算符,赋值符,new,delete,new[],delete[]。operator中的参数必须是我这么写,但如果你只是玩一下就不用了,后面的const也一样,你问我为什么,就像你问为牛顿第一定律为什么是对的一样。你不用知道它为什么是对的,只要用就可以了。

#include
using namespace std;
class str{
	public:
 		int hao,c,m,e,all;
		bool operator<(const str &s)const{
			if(s.all!=this->all)return s.all>this->all;
			else if(s.c!=this->c) return s.c>this->c;
			else return s.hao < this->hao;
		}
};
int main(){
	ios::sync_with_stdio(0),cin.tie(0);
	int n;
	cin>>n;
	vector vec(n);
	for(int i=0;i>vec[i].c>>vec[i].m>>vec[i].e,vec[i].all=vec[i].c+vec[i].m+vec[i].e,vec[i].hao=i+1;
	sort(vec.begin(),vec.end());
	for(int i = n-1;i >= n-5;i--)cout<

看懂了吗?你可以把class理解为struct,public就可以去掉了,主要看operator,this指针也是可加可不加的。主要这段代码的逻辑看没看懂,没有可以问我。

这个就拓展到这里了,谢谢指正。中间为了好理解,说的不那么精确,还请谅解。时间问题身下就讲快一点了。

贪心

c++寒假班错题分析 (2.2)_第3张图片

大家一定要认真看题,不然就像我一样。

为什么样例输出一个cindy,循环是这样的:A(Alice),B(Bob),C(Cindy),A,A,B,B,C,C,A,A,A,A,B,B,B,B,C,C,C,C······ 

大家看一下这个代码为什么是错的:

#include
using namespace std;
int main(){
	ios::sync_with_stdio(0),cin.tie(0);
	string num,las;
	int n;
	cin>>n;
	queue Q;
	for(int i=0;i>num,Q.push(num);
	las=Q.back();
	int m;
	cin>>m;
	num="";
	for(int i=0,t=1;i

首先t++,应该换成t*=2,这就是我不好好审题。if(num==las)要换到for循环的开头,不然少加一次

#include
using namespace std;
int main(){
	ios::sync_with_stdio(0),cin.tie(0);
	string num,las;
	int n;
	cin>>n;
	queue Q;
	for(int i=0;i>num,Q.push(num);
	las=Q.back();
	int m;
	cin>>m;
	num="";
	for(int i=0,t=1;i

这就AC了。

纪念评分组

c++寒假班错题分析 (2.2)_第4张图片

先看数据范围,3e4,遍历O(N^2)9个亿,直接炸。

#include 
using namespace std;
int main() {
  int w, n, cnt = 0;
  cin >> w >> n;
  vector A(n);
  for (int &a : A) cin >> a;
  sort(begin(A), end(A));
  for (int l = 0, r = n - 1; l <= r; cnt++, r--) {
    if (A[l] + A[r] <= w) l++;  // 每次配对A[r]
  }
  printf("%d\n", cnt);
  return 0;
}

有人说你这很不严谨呀,如果输入

100 1

90 

你这不就90+90了吗,我也想过,可一试,是对的,应为循环一次,不管判断成不成立,cnt++,r--下一次就不循环了,是吧。

最长公共子序列

这个题最经典,题目都不用说了

ABCBDAB
BDCABA

输出4,因为ABCBDABBDCABA的最长公共子序列可以是BCBA或者BCAB或者BDAB

代码直接说:
 

#include 
using namespace std;
const int NN = 1000 + 4;
int D[NN][NN];
int main() {
  string X, Y;    // 声明两个字符串X和Y
  cin >> X >> Y;  // 输入两个字符串X和Y
  // D[i][j]表示字符串X的前i个字符和字符串Y的前j个字符的最长公共子序列的长度
  int m = X.size(), n = Y.size();  // 获取两个字符串的长度
  for (int i = 0; i <= m; i++)
    for (int j = 0; j <= n; j++) {
      int &d = D[i][j];  // 使用引用d简化对D[i][j]的操作
      if (i == 0 || j == 0)
        d = 0;  // LCS的长度初始化为0
      else {
        if (X[i - 1] == Y[j - 1])  // 如果X的第i个字符和Y的第j个字符相同
          d = D[i - 1][j - 1] + 1;  // LCS长度增加1
        else  // 如果不同,则取两种情况的较大值
          d = max(D[i - 1][j], D[i][j - 1]);
      }
    }
  printf("%d\n", D[m][n]);  // 输出整个字符串X和Y的最长公共子序列的长度
  return 0;
}

你可能感兴趣的:(c++,算法,开发语言)