嫣然一笑I

【题目描述】
网页浏览器者有后退与前进按钮,一种实现这两个功能的方式是用两个栈,
“前进栈”、“后退栈”。
这里你需要实现以下几个功能:
BACK: 如果“后退栈”为空则忽略此命令。否则将当前两面压入“前进栈”,
从“后退栈”中取出栈顶页面,并设置为当前页面。
FORWARD: 如果“前进栈”为空则忽略此命令。否则将当前两面压入“后
退栈”,从“前进栈”中取出栈顶页面,并设置为当前页面。
VISIT: 将当前页面压入“后退栈”、并将当前页面置为指定页面,并将“前
进栈”置空。
QUIT: 退出。
假设此浏览器初始页面为http://www.acm.org/
【输入格式】
输入为一系列命令:BACK, FORWARD, VISIT 和QUIT,页面网址为不含空
格的字符串
假设任一时刻任意时刻两个栈中的元素都不会超过100。
最后一个命令为QUIT。
【输出格式】
输对于除QUIT 外所有命令,输出当前页面(网址)
如果该命令被忽略则输出“Ignored”。
【样例输入】


题解:

#include<iostream>
#include<cstdio>
#include<stack>
using namespace std;
stack<string> s1;
stack<string> s2;
int main()
{
    string now;
    now="http://www.acm.org/";
     string s;
     string x;
     while(cin>>s)
     {
        if(s=="QUIT")
        {
            break;
        }
        else if(s=="VISIT")
        {
            cin>>x;
            s2.push(now);
            cout<<x<<endl;//换行~~~~(>_<)~~~~ 
            now=x;
            while(!s1.empty())
            {
                s1.pop();
            }
        }
        else if(s=="BACK")
        {
           if(s2.empty())
            {
                cout<<"Ignored"<<endl;
            }
            else
            {
                s1.push(now);
                cout<<s2.top()<<endl;
                now=s2.top();
                s2.pop();           
            }   
        }
        else if(s=="FORWARD")
        {
            if(s1.empty())
            {
                cout<<"Ignored"<<endl;
            }
            else
            {
                s2.push(now);
                cout<<s1.top()<<endl;
                now=s1.top();
                s1.pop();
            }
        }
     }
     return 0;
}

——————————————华丽的分隔线——————————————


n,m,h均大于等于0,小于等于1005。

样例的解释:
这里写图片描述
思路:因为给你的是主视图和左视图,我们可以考虑某些的地方在主视图和左视图在是都可以看到的,所以相等的左视图的高和主视图高是可以用一块来搞定的,不同的高就可以用一个数组记录一下,主视图和左视图若有相同的高可以用一个高来搞定,而max则可以左视图和主视图中交集取min。

题解:

#include<iostream>
#include<cstdio>
#include<set>
#include<algorithm>
using namespace std;
int a[1005],b[1005];
int f[1005];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    long long maxn=0;
    long long minn=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        f[a[i]]++;//记录出现的高
        minn+=a[i];//无论是主视图还是左视图,选择一方的高全部加上。
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&b[i]);
    if(f[b[i]]>0)
    {
        f[b[i]]--;//出现重复的高就减去
    }
    else if(f[b[i]]<=0)
    {
        minn+=b[i];//没出现的高就加上
    }
}
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                maxn+=min(a[i],b[j]);//最大值
            }
        }
        printf("%lld %lld",minn,maxn);
        return 0;
}

——————————-我是华丽的分割线————————————–


【问题描述】
栈是一种强大的数据结构,它的一种特殊功能是对数组进行排序。例如,借
助一个栈,依次将数组 1,3,2 按顺序入栈或出栈,可对其从大到小排序:
1 入栈;3 入栈;3 出栈;2 入栈;2 出栈;1 出栈。
在上面这个例子中,出栈序列是 3,2,1,因此实现了对数组的排序。
遗憾的是,有些时候,仅仅借助一个栈,不能实现对数组的完全排序。例如
给定数组 2,1,3,借助一个栈,能获得的字典序最大的出栈序列是 3,1,2:
2 入栈;1 入栈;3 入栈;3 出栈;1 出栈;2 出栈。
请你借助一个栈,对一个给定的数组按照出栈顺序进行从大到小排序。当无
法完全排序时,请输出字典序最大的出栈序列。
【输入格式】
输入共2行。
第一行包含一个整数N,表示入栈序列长度。
第二行包含N个整数,表示入栈序列。输入数据保证给定的序列是1到 n 的全
排列,即不会出现重复数字。
【输出格式】
仅一行,共N个整数,表示你计算出的出栈序列。
【样例输入】
3
2 1 3
【样例输出】
3 1 2
【样例解释】
这回山里有座塔。
【数据规模与约定】
对于30%的数据,1 ≤ N≤ 10^3。
对于60%的数据,1 ≤ N≤ 10^5。
对于100%的数据,1 ≤ N ≤ 10^6。

题解(贪心):

#include<iostream>
#include<cstdio>
#include<stack>
using namespace std;
int a[1000000+10];
int mx[1000000+10];
stack<int>q;
int main()
{
    //freopen("haha.in","r",stdin);
    //freopen("haha.out","w",stdout);
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    for(int i=n;i>=1;i--)
    {
        mx[i]=max(mx[i+1],a[i]);
    }
    int now=1;
    while(1)
    {
        while(now<=n&&(q.empty()||q.top()<mx[now]))
        {
            q.push(a[now]);
            now++;
        }
        if(now>n)
        {
        break;
        }   
        printf("%d ",q.top());
        q.pop();        
    }
    while(!q.empty())
    {
        printf("%d ",q.top());
        q.pop();
    }
    return 0;
}

—————————————我是华丽的分割线———————————————

【问题描述】
小 Q 对计算几何有着浓厚的兴趣。他经常对着平面直角坐标系发呆,思考
一些有趣的问题。今天,他想到了一个十分有意思的题目:
首先,小 Q 会在x轴正半轴和y轴正半轴分别挑选n个点。随后,他将x轴的
点与y轴的点一一连接,形成x条线段,并保证任意两条线段不相交。小 Q 确定
这种连接方式有且仅有一种。最后,小 Q 会给出m个询问。对于每个询问,将会
给定一个点(x,y)
),请回答线段 OP 与n条线段会产生多少个交点?
小 Q 找到了正在钻研数据结构的你,希望你可以帮他解决这道难题。
【输入格式】
第1行包含一个正整数n,表示线段的数量;
第2行包含n个正整数,表示小 Q 在x轴选取的点的横坐标;
第3行包含n个正整数,表示小 Q 在y轴选取的点的纵坐标;
第 4 行包含一个正整数m,表示询问数量;
随后m行,每行包含两个正整数x和y,表示询问中给定的点的横、纵坐标。
【输出格式】
共m行,每行包含一个非负整数,表示你对这条询问给出的答案。
【样例输入】
3
4 5 3
3 5 4
2
1 1
3 3
【样例输出】
0
3

题解(二分):

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
double a[200000+10];
double b[200000+10];
double c[200000+10];
int n;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lf",&a[i]);
    }
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++)
    {
        scanf("%lf",&b[i]);
    }
    sort(b+1,b+n+1);
    for(int i=1;i<=n;i++)
    {
        c[i]=-b[i]/a[i];
    }
    int m;
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        double x,y;
        scanf("%lf%lf",&x,&y);
        int l=0,r=n;
        int ans=0;
        while(l<=r)
        {
            int mid=(l+r)/2;
            if((c[mid]*x+b[mid])-y<=0.00001)
            {
                l=mid+1;
                ans=max(ans,mid);
            }
            else
            {
                r=mid-1;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

————————————————我是华丽的分割线—————————————————-

【问题描述】
从1 − N中找一些数乘起来使得答案是一个完全平方数,求这个完全平方数
最大可能是多少。
【输入格式】
第一行一个数字N。
【输出格式】
一行一个整数代表答案对100000007取模之后的答案。
【样例输入】
7
【样例输出】
144
【样例解释】
但是塔外面有东西。
【数据规模与约定】
对于20%的数据,1 ≤ N ≤ 100。
对于50%的数据,1 ≤ N≤ 5000。
对于70%的数据,1 ≤ N ≤ 10^5。
对于100%的数据,1 ≤ N ≤ 5 × 10^6。

题解(分解质因数):

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
bool prime[5100000];
long long a[5100000];
const long long mod=100000007;
long long ksm(long long x,long long y)
{
    if(y==0)
    {
        return 1;
    }
    long long ans=ksm(x,y/2);
    ans=((ans%mod)*(ans%mod))%mod;
    if(y%2==1)
    {
        ans=((ans%mod)*(x%mod))%mod;
    }
    return ans;
}
int main()
{
    //freopen("hao.in","r",stdin);
    //freopen("hao.out","w",stdout);
    memset(prime,1,sizeof(prime));
    long long n;
    scanf("%lld",&n);
    for(long long i=2;i<=sqrt(n);i++)
    {
        if(prime[i])
        {
            for(long long j=i*2;j<=n;j+=i)
            {
                prime[j]=0;
            }
        }
    }
    for(long long i=2;i<=n;i++)
    {
        if(prime[i])
        {
            long long x=n;
            while(x)
            {
            a[i]+=x/i;
            x/=i;   
            }
        }
    }
    long long ans=1;
    for(long long i=1;i<=n;i++)
    {

        if(a[i]%2==1)
        {
            a[i]--;
        }
        if(a[i])
        {
        long long sum=ksm(i,a[i]);
        ans=((ans%mod)*(sum%mod))%mod;
        }
    }
    printf("%lld",ans);
    return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值