算法题目中经典问题(易错点)

本文详细讲解了二维数组在函数传参中的两种常见方法,包括形参为数组和指针,以及避免全局变量带来的问题。同时介绍了进制转换中的字符串存储技巧,结构体数组的使用,以及算法竞赛中常遇到的无穷大处理和优先队列/快速排序的定制。适合提升算法竞赛中的核心技能。

(一).二维数组的传参问题

1.方法一:形参为二维数组并给定第二维长度

此方法是最简单最直观的方法,形参与实参一样,容易理解。

声明:void solve(int n, char subargs[][5]);
调用:solve(3, args);

举例:

#include <stdio.h>
 
void solve(int n, char subargs[][5])
{
    int i;
    for (i = 0; i < n; i++) {
    	printf("subargs[%d] = %s\n", i, subargs[i]);
    }
}
 
int main()
{
    char args[][5] = {"abc", "def", "ghi"};
    solve(3, args);
    return 0;
}

在这里插入图片描述

2.方法二:形参为指向数组的指针并给出数组长度

声明:void subfun(int n, char (*subargs)[5]);
调用:subfun(3, args);
#include <stdio.h>
 
void subfun(int n, char (*subargs)[5])
{
    int i;
    for (i = 0; i < n; i++) {
    	printf("subargs[%d] = %s\n", i, subargs[i]);
    }
}
 
int main()
{
    char args[][5] = {"abc", "cde", "ghi"};
    subfun(3, args);
}

在这里插入图片描述

3.二维数组定义为全局变量

这样就不用因为参数问题耽误时间

全局变量的定义:double p[10000+10][3];
声明:double Solve(); 
调用:Solve();

实例:
算法题目——二次函数三分求极值(HDU-3714)

(二).多组测试控制台数据,输入到文件结束

while(scanf("%d",&n)!=EOF)

运行程序按CTRL+Z键,即会显示“^Z",再次按回车键即可退出程序。

#include <stdio.h>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int main()
{    
	int n;
	vector<int> vec;
	while(scanf("%d",&n)!=EOF)
	{		
		vec.push_back(n);
	 }
	  
	for(int i=0;i<vec.size();i++)
	{
		cout<<vec[i]<<endl;
	}
	return 0;
}

在这里插入图片描述
实例:算法题目——整数划分(HRBUST-2004)

(三).进制转换中的小问题

1.使用字符串来存储,每一位

实例:
算法题目——Problem A 二进制(北邮机试)

(四).结构体数组的使用

参考文章:C | struct结构体

(五).注意条件里的等于(判断)是双等号

if(str[x+dx[i]][y+dy[i]]=='1')

(六).开数组和数据时,数据类型一定要够大,不然可能有问题此外一定要把用到的变量放到全局中

#define ll long long
#define MAX 100005
ll nums[MAX];
ll sum,S;

例题:算法题目——子序列和问题(poj-3061)

(七) 在算法竞赛中,我们常常需要用到设置一个常量用来代表“无穷大”。

#define INF 0x3f3f3f3f//设立一个很大很大的数

0x3f3f3f3f 0x开头的 是十六进制常数, 等于 十进制 1061109567
等于 二进制: 00111111 00111111 00111111 00111111
const int inf=0x3f3f3f3f – 声明 inf 是 const int型 , const 表示 inf 一旦有了值以后就不允许(通过赋值 来)改变它的值.
0x3f3f3f3f * 2 = 2122219134,无穷大相加依然不会溢出。
可以使用memset(array, 0x3f, sizeof(array))来为数组设初值为0x3f3f3f3f,因为这个数的每个字节都是0x3

例题:算法题目——子序列和问题(poj-3061)

(八)优先队列(默认为最大根)的最小根或快排(默认为从小到大)的从大到小

优先队列的写法

#include <iostream>
#include <queue> 
using namespace std; 
struct Node{
    int x, y;
    Node( int a= 0, int b= 0 ):
        x(a), y(b) {}
};

bool operator<( Node a, Node b ){//升序 
    if( a.x== b.x ) return a.y> b.y;
    return a.x> b.x; 
}

/*
bool operator<( Node a, Node b ){//降序 
   	if( a.x== b.x ) return a.y< b.y;
    	return a.x< b.x; 
}
 */
int main(){
    priority_queue<Node> q;     
    for( int i= 0; i< 10; ++i )
    q.push( Node( rand(), rand() ) );  //构造函数   
    while( !q.empty() ){
        cout << q.top().x << ' ' << q.top().y << endl;
        q.pop();
    }     
    getchar();
    return 0;
}



在这里插入图片描述

快排的写法

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
bool cmp(int a,int b)//降序的写法(从大到小) 
{
	return a>b;
}
int main()
{
    int a[5]={1,3,4,2,5};
    sort(a,a+5,cmp);
    for(int i=0;i<5;i++)
            cout<<a[i]<<' ';
    return 0;
 }


在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值