算法竞赛入门经典第三章笔记

例题3-6 最长回文子串

这道题有个好思路即是,找回文的时候,不是从头到尾,而是从中间向两边扩散。

#include <cstdio>
#include <cstring>
#include <cctype>

#define MAXN 5000 + 10

char buf[MAXN];
char str[MAXN];
int pos[MAXN];

void main(){
	
	while(fgets(buf, sizeof(str), stdin)){
		int len = 0 , p = 0, max = 0, left = 0, right = 0;
		len = strlen(buf);
		for(int i = 0; i < len; i++){
			if(isalpha(buf[i])){
				str[p] = toupper(buf[i]);
				pos[p] = i;
				p++;
			}
		}

		for(int i = 0; i < p; i++){
			for(int j = 0; (i-j) >= 0 && (i+j) < p; j++){
				if(str[i-j] != str[i+j])
					break;
				if(j*2 + 1 > max){
					max = j*2 + 1;
					left  = pos[i-j];
					right = pos[i+j];
				}								
			}

			for(int j =0; (i-j) >= 0 && (i+j+1) < p; j++){
				if(str[i-j] != str[i+j+1])
					break;
				if(j*2+2 > max){
					max = j*2 + 2;
					left  = pos[i-j];
					right = pos[i+j+1];
				}	
			}
		}

		for(int i = left; i <= right; i++){
			printf("%c", buf[i]);
		}
		printf("\n");
	}
}


习题3-1 分数统计

这道题写得有点复杂,重要是想顺带复习学习一下容器的用法

#include <iostream>
#include <map>
#include <vector>
#include <algorithm>

using namespace std;

struct node{
	node(){}
	node(double s, int c){scroe = s; counter = c;}
	double scroe;
	int counter;
};


bool sortNode(const node *v1, const node *v2){
	if(v1->counter == v2->counter){
		return v1->scroe > v2->scroe;
	}else{
		return v1->counter > v2->counter;
	}
}

void main(){
	map<double, node> nodeMap;
	vector<node*> nodeVec;
	double score;
	while(cin >> score){
		map<double, node>::iterator it = nodeMap.find(score);
		if(it == nodeMap.end()){
			nodeMap.insert(make_pair(score, node(score, 1)));
		}else{
			it->second.counter++;
		}
	}

	for(map<double, node>::iterator it = nodeMap.begin(); it != nodeMap.end(); it++){
		nodeVec.push_back(&(it->second));
	}

	sort(nodeVec.begin(), nodeVec.end(), sortNode);

	int maxCounter = nodeVec[0]->counter;
	for(int i = 0; i < nodeVec.size(); i++){
		if(nodeVec[i]->counter < maxCounter)
			break;
		cout << nodeVec[i]->counter << " " << nodeVec[i]->scroe << endl;
	}
}
还有几点注意的:

1:vector里不能放引用类型(?)

2:struct/类,当自己写了一个构造函数后,则默认构造函数自动失效

3:map 的 insert 用make_pair  做键值对,在使用vector.resize(n),后vector的size就会变成n,即默认会构建n个默认的对象。


习题 3-3 乘积的末3位

这道题和第二章的阶乘有些类似,即若加,减,乘的整数表示式除以正整数n的余数,可以在每步计算之后对n取余,结果不变。

#include<iostream>
#include<string>

using namespace std;

#define END_NUM 1000

void main(){
	long num = 0;
	int x = 1;
	string str;
	while(cin >> str){
		//先判断str是否为数字
		bool isNum = true;
		for(int i=0; i<str.size(); i++){
			if(!isdigit(str[i])){
				isNum = false;
				break;
			}
		}

		if(!isNum) continue;

		//将str转换为数字
		sscanf(str.c_str(), "%ld", &num);

		//取后三位
		num%=END_NUM;
		
		//开始计算后三位乘积
		x = x*num%END_NUM;
	}
	cout << x;
}

这道题还有几个点:

1:isdigit() 函数,判断是否char型数据是否为数字(即‘0’~‘9’)

2:sscanf,sprintf,stringstream的用法,这里不再赘述,这几个函数在字符串或string的操作上有很多的用处


习题 3-5,3-7 进制转换

两题合一,进制转换问题

#include<iostream>
#include<vector>

using namespace std;

void main(){
	int b = 0;	
	int n = 0;

	vector<int> vec;

	cin >> b >> n;
	
	while(n > 0){
		vec.push_back(n % b);
		n /= b;
	}

	for(int i = vec.size()-1; i >= 0; i--){
		cout << vec[i];
	}

	cout << endl;

	cin >> b >> n;
	int c = 1,i = 0;
	while(n > 0){
		i += c*(n%10);
		n /= 10;
		c*=b;
	}
	cout << i << endl;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值