从零单排7

这个教室一会儿有课,一会儿去机房,先整理一下刚刚做的吧

昨天这个博客第一次有人回复了~还是我搜题解经常搜到的大神~好开心~

另外今天搜题解的时候又看到了几个熟悉的ID~在杭电经常见得到

e) RMQ算法
4. 学会分析与计算复杂程序的时间复杂度
5. 学会使用栈与队列等线性存储结构


刚刚看了RMQ问题的ST算法和栈(PS下午看了一下队列的内容,好多都是优先队列和单调队列什么的。。。以后再看~)

关于RMQ问题的ST算法,属于动态规划,将模版下去搞懂。

栈属于数据结构的基本内容,拿了火车进站,括号匹配还有表达式求值三个题练习了一下,一会儿去拿数据结构课本到机房练习一下

上午先不做新题了,把栈复习一下,然后熟悉STL中栈和队列的模版,再巩固一下RMQ


以下题解:

hdu 3486:http://acm.hdu.edu.cn/showproblem.php?pid=3486

/*
RMQ模版题
这个题是从网上直接搜来的模版
效率神马的先不管了
先会用模版再说...
*/
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define M 222222
#define MAXN 500
#define MAXM 500
int dp[M][30];
int dp2[MAXN][MAXM][10][10];
int l[M],r[M],a[M];
char s[1002];
/*
*一维RMQ ST算法
*构造RMQ数组 makermq(int n,int b[]) O(nlog(n))的算法复杂度
*dp[i]j] 表示从i到i+2^j -1中最大的一个值
*dp[i][j]=max{dp[i][j-1],dp[i+2^(j-1)][j-1]}
*查询RMQ rmq(int s,int v)
*将s ->v 分成两个2^k的区间
*即 k=(int)log2(s-v+1)
*查询结果应该为 max(dp[s][k],dp[v-2^k+1][k])
*/
int rmq(int s,int v)
{
    int k=(int)(log((v-s+1)*1.0)/log(2.0));
    return max(dp[s][k],dp[v-(1<<k)+1][k]);
}
void makermq(int n,int b[])
{
    int i,j;
    for(i=1;i<=n;i++)
        dp[i][0]=b[i];
    for(j=1;(1<<j)<=n;j++)
        for(i=1;i+(1<<j)-1<=n;i++)
            dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
int check(int len,int t,int k)
{
    int i,j,ans=0;
    for(i=1;i<=t;i++)
    {
        ans+=rmq((i-1)*len+1,i*len);
        if(ans>k)
			return 1;
    }
    return 0;
}
/*
*二维RMQ ST算法
*构造RMQ数组 makermq(int n,int m,int b[][]) O(n*m*log(n)*log(m))算法复杂度
*dp2[row][col][i][j] 表示 行从row ->row +2^i-1 列从col ->col +2^j-1 二维区间里最大值
*dp2[row][col][i][j] = 下行
*max{dp2[row][col][i][j-1],dp2[row][col][i-1][j],dp2[row][col+2^(j-1)][i][j-1],dp2[row+2^(i-1)][col][i-1][j]}
*查询RMQ rmq(int sx,int ex,int sy,int ey)
*同一维的将sx->ex 分为两个2^kx区间 将 sy->ey分为两个2^ky的区间
*kx=(int)log2(ex-sx+1) ky=(int)log2(ey-sy+1)
*查询结果为
*max{dp2[sx][sy][kx][ky],dp2[sx][ey-2^ky+1][kx][ky],dp2[ex-2^kx+1][sy][kx][ky],dp2[ex-2^kx+1][ey-2^ky+1][kx][ky]}
*/

void makermq(int n,int m,int b[][MAXM])
{
    int row,col,i,j;
    for(row=1;row<=n;row++)
        for(col=1;col<=m;col++)
            dp2[row][col][0][0]=b[row][col];
    for(i=0;(1<<i)<=n;i++)
        for(j=0;(1<<j)<=m;j++)
        {
            if(i==0&&j==0) continue;
            for(row=1;row+(1<<i)-1<=n;row++)
                for(col=1;col+(1<<j)-1<=m;col++)
                {
                if(i==0)
                    dp2[row][col][i][j]=max(dp2[row][col][i][j-1],dp2[row][col+(1<<(j-1))][i][j-1]);
                else
                    dp2[row][col][i][j]=max(dp2[row][col][i-1][j],dp2[row+(1<<(i-1))][col][i-1][j]);
                }
        }
}
int rmq(int sx,int ex,int sy,int ey)
{
int kx=(int)(log((ex-sx+1)*1.0)/log(2.0)),ky=(int)(log((ey-sy+1)*1.0)/log(2.0));
return max(max(dp2[sx][sy][kx][ky],dp2[sx][ey-(1<<ky)+1][kx][ky]),max(dp2[ex-(1<<kx)+1][sy][kx][ky],dp2[ex-(1<<kx)+1][ey-(1<<ky)+1][kx][ky]));
}
int main()
{
    int u,v,n,q,m;
    while(scanf("%d%d",&n,&q),(n>=0&&q>=0))
    {
        int i,j,l=1,r=n,ans=-1;
        for(m=0,i=1;i<=n;i++)
		{
			scanf("%d",&a[i]);
			m+=a[i];
		}
        if(m<=q)
		{
			printf("%d\n",ans);
			continue;
		}
        makermq(n,a);
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(check(n/mid,mid,q)) 
			{
				r=mid-1;
				ans=mid;
			}
            else 
				l=mid+1;
        }
        printf("%d\n",ans);
    }
    return 0;
}

hdu 1022: http://acm.hdu.edu.cn/showproblem.php?pid=1022

/*
栈的使用
哈哈神说要有光,于是有了STL
*/
#include<iostream>
#include<stack>
char a[1005];
char b[1005];
int mark[1005];
using namespace std;
int main()
{
	stack<char>s;
	int n;
	while(cin>>n)
	{
		getchar();
		for(int i=0;i<n;i++)
		{
			cin>>a[i];
		}
		getchar();
		for(int i=0;i<n;i++)
		{
			cin>>b[i];
		}
		getchar();
		while(!s.empty())
		{
			s.pop();
		}
		s.push(a[0]);
		int j=0;
		int k=0;
		mark[k++]=0;
		for(int i=1;i<=n;i++)
		{
			while(!s.empty()&&s.top()==b[j])
			{
				mark[k++]=1;
				j++;
				s.pop();
			}
			if(i!=n)
			{
				s.push(a[i]);
				mark[k++]=0;
			}
		}
		if(j==n)
		{
			cout<<"Yes."<<endl;
			for(int i=0;i<2*n;i++)
			{
				if(mark[i])
				{
					cout<<"out"<<endl;
				}
				else
				{
					cout<<"in"<<endl;
				}
			}
			cout<<"FINISH"<<endl;
		}
		else
		{
			cout<<"No."<<endl<<"FINISH"<<endl;
		}
	}
	system("pause");
	return 0;
}

hdu 1870: http://acm.hdu.edu.cn/showproblem.php?pid=1870

/*
栈的使用-括号匹配
终于会用STL啦~
PS:我还在想为什么不能反向拆盒子。。 
*/
#include<iostream>
#include<stack>
using namespace std;
stack<char> s;
char str[1005];
int main()
{
	while(cin>>str)
	{
		while(!s.empty())
		{
			s.pop();
		}
		int len=strlen(str);
		int cnt=0;
		for(int i=0;i<len;i++)
		{
			if(str[i]=='(')
			{
				s.push(str[i]);
				cnt++;
			}
			else if(str[i]==')')
			{
				s.pop();
				cnt--;
			}
			else
			{
				break;
			}
		}
		if(!s.empty())
		{
			cout<<cnt<<endl;
		}
		else
		{
			cout<<"0"<<endl;
		}
	}
	system("pause");
	return 0;
}
			

hdu 1237: http://acm.hdu.edu.cn/showproblem.php?pid=1237

/*
栈的应用-简单计算器计算
原理都懂..
处理好麻烦
这份代码是搜刮来的写的可读性比较好的一份
回去看看数据结构书再敲一遍去 
*/
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
int main()
{
    int i;
    double a,b;
    char s[1005],c;
    while(gets(s)&&strcmp(s,"0")!=0)
    {
        stack<char>op;
        stack<double>num;
        for(i=0;s[i];i++)
        {
            if(s[i]>='0'&&s[i]<='9')
            {
                a=0;
                while(s[i]>='0'&&s[i]<='9')
                {
                    a=a*10+s[i]-'0';
                    i++;
                }
                i--;
                num.push(a);
            }
            else if(s[i]=='-'||s[i]=='+')
            {
                if(!op.empty())
                {
                    c=op.top();
                    op.pop();
                    a=num.top();
                    num.pop();
                    b=num.top();
                    num.pop();
                    if(c=='+')
                        a=a+b;
                    else
                        a=b-a;
                    num.push(a);
                    op.push(s[i]);
                }
                else
                    op.push(s[i]);
            }
            else if(s[i]=='/'||s[i] == '*')
            {
                char ch=s[i];
                b=0;
                i+=2;
                while(s[i]>='0'&&s[i]<='9')
                {
                    b=b*10+s[i]-'0';
                    i++;
                }
                i--;
                a=num.top();
                num.pop();
                if(ch == '/')
                	a=a/b;
                else
                	a=a*b;
                num.push(a);
            }
        }
        while(!op.empty())
        {
            c=op.top();
            op.pop();
            a=num.top();
            num.pop();
            b=num.top();
            num.pop();
            if(c=='+')
                a+=b;
            else
                a=b-a;
            num.push(a);
        }
        printf("%.2f\n",num.top());
    }
    return 0;
}

看到好多acmer在吐槽成绩不太好没法保研什么的...

额。。

我刚刚起步所以以前都用来用功读书了(不要吐槽。。。)

所以成绩还好可以保研。。

不过话说我既然选择走算法竞赛这条路了

肯定是想毕业工作的...

读研多无聊。。。。。。

好吧当我年少无知吧。。。

加油~!

想想岛娘的一句话就觉得霸气~

“题数碾压,不要不服~!"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值