A-Maximum Multiple (hdu 6298)
http://acm.hdu.edu.cn/showproblem.php?pid=6298
好题啊好题
因为 能分解成三个分数的就只有上面这 个,所以同时乘 就表示 能分解的三个数,然后这三个满足条件的取最大就行了。。。。好题~
#include"bits/stdc++.h"
using namespace std;
typedef long long LL;
const LL maxn=5e5+5;
int main()
{
LL N,T;
cin>>T;
while(T--)
{
scanf("%lld",&N);
LL ans=-1;
if(N%2==0&&N%3==0&&N%6==0)ans=max(ans,(N/2)*(N/3)*(N/6));
if(N%3==0)ans=max(ans,(N/3)*(N/3)*(N/3));
if(N%4==0&&N%2==0)ans=max(ans,(N/2)*(N/4)*(N/4));
printf("%lld\n",ans);
}
}
D-Distinct Values (hdu 6301)
http://acm.hdu.edu.cn/showproblem.php?pid=6301
题意:给 个区间,每个区间内的数不能重复,要求构造出的数列的字典序最小
思路:把能够填的数先弄进一个优先队列中,然后每个区间一个一个取数出来填,而不在这个区间内的之前的数又能够用了,就阔以把他们又放回队列里面等待取出来
#include"bits/stdc++.h"
#define out(x) cout<<#x<<"="<<x
using namespace std;
typedef long long LL;
const LL maxn=1e5+5;
int R[maxn],a[maxn];//R[i]表示[i,R[i]]这个区间内的数不能重复
priority_queue<int,vector<int>,greater<int> >que;//队列里保存的相当于是可以用来填的数
int main()
{
int T;
cin>>T;
while(T--)
{
while(!que.empty())que.pop();
int N,M;
cin>>N>>M;
for(int i=1;i<=N;i++)
{
R[i]=i; //R[i]初始化
que.push(i); //把能用的数都先放到队列里面
}
for(int i=1;i<=M;i++)
{
int l,r;
scanf("%d%d",&l,&r);
R[l]=max(R[l],r); //比如先出现[2,5],后出现[2,3]应该选大的
}
int pre=1; //表示上次处理的开始
int now=0; //表示当前处理到哪里了
for(int i=1;i<=N;i++)
{
if(R[i]<=now)continue;
for(int j=pre;j<i;j++)
{
que.push(a[j]); //这次区间外面的上个区间的数要收回继续用来填
}
while(now<R[i])
{
a[++now]=que.top();
que.pop();
}
pre=i;
}
for(int i=1;i<=N;i++)
{
if(i<N)cout<<a[i]<<" ";
else cout<<a[i]<<endl;
}
}
}