【题目描述】
网页浏览器者有后退与前进按钮,一种实现这两个功能的方式是用两个栈,
“前进栈”、“后退栈”。
这里你需要实现以下几个功能:
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;
}