hdu 6298 Maximum Multiple
题目要求把n拆成3个数,且都是n的因子切求和为n 其要求输出的3个数的乘积最大
那么就要把这3个数尽量靠近,1:1:1为最好,但如果不能拆成这样的话,就要想到1:1:2这种情况,
因为111的情况下,1+1+1=3且1|3,112的情况下 1+1+2=4且1|4,2|4
所以122是不行的,因为1+2+2=5,但是2不能整除5所以只有n能整除3或者4才能输出答案。然后按比例求个乘积即可。
#include<bits/stdc++.h>
using namespace std;
int main(){
long long n;
int t;
cin>>t;
while(t--)
{
scanf("%lld",&n);
if(n%3!=0&&n%4!=0)
cout<<"-1"<<endl;
else if(n%3==0)
{
long long a=n/3;
long long ans=a*a*a;
printf("%lld\n",ans);
}
else if(n%4==0)
{
long long a=n/2;
long long b=n/4;
long long ans=a*b*b;
printf("%lld\n",ans);
}
}
return 0;
}
hdu 6300 Triangle Partition
给3n个点,求能组成n个三角形的组合方式且每2个三角形之间没有重合(包括点)
那么我们只要将点按照x坐标从左到右排序,然后一次每行输出3个点的id即可
#include<bits/stdc++.h>
using namespace std;
struct node{
long long a,b;
int id;
}p[99999];
bool cp(node x,node y)
{
if(x.a!=y.a)return x.a<y.a;
return x.b<y.b;
}
int main(){
long long n;
int t;
cin>>t;
while(t--)
{
scanf("%lld",&n);
for(int i=1;i<=n*3;i++)
scanf("%lld%lld",&p[i].a,&p[i].b),p[i].id=i;
sort(p+1,p+1+3*n,cp);
for(int i=1;i<=n*3;i+=3)
printf("%d %d %d\n",p[i].id,p[i+1].id,p[i+2].id);
}
return 0;
}
hdu 6038 Time Zone
模拟 ,注意下输入的东西即可
#include<bits/stdc++.h>
using namespace std;
#define LL long long int
int T;
int x,y;
char op[11];
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d %d UTC%s",&x,&y,&op);
int opp=0;
int oppp=0;
int flag;
if(op[0]=='-') flag=-1;
else flag=1;
for(int i=1;op[i];i++)
{
if(op[i]>='0'&&op[i]<='9')
opp=opp*10+op[i]-'0';
if(op[i]=='.')
{
oppp=op[i+1]-'0';
break;
}
}
opp=opp*60+oppp*6;
opp*=flag;
opp-=480;
y+=opp;
while(y<0)
{
y+=60;x--;
}
while(y>59)
{
y-=60;x++;
}
y=(y+600)%60;
x=(x+240)%24;
printf("%02d:%02d\n",x,y);
}
return 0;
}
hdu 6301 Distinct Values
首先按照左端排序,然后长区间放前面。
暴力会超时,优化方法就利用集合来快速找到需要放进去的数字。
用优先队列也可以
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m,t,ans[100006];
struct node
{
int l,r,id;
friend bool operator <(node a,node b)
{
return a.l==b.l?a.r>b.r:a.l<b.l;
}
}q[100006];
set<int>s;
int main()
{
scanf("%d",&t);
while(t--)
{
s.clear();
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
s.insert(i);
for(int i=1;i<=m;i++)
scanf("%d%d", &q[i].l, &q[i].r);
sort(q+1, q+m+1);
int r=0,l=1;
for(int i=1;i<=m;i++)
{
if(q[i].r <= r)
continue;
if(q[i].l > r)
{
while(r<q[i].l)
ans[++r]=1;
while(l<q[i].l) s.insert(ans[l++]);
if((*s.begin())==1) s.erase(s.begin());
while(r<q[i].r)
{
ans[++r]=(*s.begin());
s.erase(s.begin());
}
}
else if(q[i].l<=r)
{
while(l<q[i].l) s.insert(ans[l++]);
while(r<q[i].r)
{
ans[++r]=(*s.begin());
s.erase(s.begin());
}
}
}
while(r<n)
ans[++r]=1;
for(int i=1;i<=n;i++)
{
if(i>1)cout<<" ";
cout<<ans[i];
}
cout<<endl;
}
return 0;
}
hdu 6299 Balanced Sequence
给出n个小括号串,让你将它们头尾拼起来,然后处理括号匹配问题求括号匹配的最大长度。
首先我们对于输入进来的每一个字符串,都可以直接算得它本身的括号匹配的长度。
然后它就会剩下 a个右括号和b个左括号的组合。类似于))))))(((((((((这样的情况,只不过a和b不一定相同。
那么问题就变成去拼这些东西求括号匹配最大长度。
我们肯定让 )))((((((((((((((((这种左括号大于右括号的尽量在左边,让)))))))))))))))))))(((这样的尽量在右边
那如果都是))))))))))))))))))))))))((这样的 那么我们就让(越少的放在最后面,
如果都是))(((((((((((((((((((这样的,我们就让)越少的放在最前面 ,那么最后会是 )))...............(((这样的情况就是最优的
#include<bits/stdc++.h>
using namespace std;
struct node{
int l,r;
}p[111111];
char s[111111];
bool cp(const node &x,const node &y)
{
if(x.l>x.r&&y.l<=y.r)
return 1;
if(x.r>=x.l&&y.r<y.l)
return 0;
if(x.r>=x.l&&y.r>=y.l)
return x.l>y.l;
return x.r<y.r;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
int ans=0;
for(int j=0;j<n;j++)
{
scanf("%s",s);
int l=strlen(s);
int jl=0;
int jr=0;
for(int i=0;i<l;i++)
{
if(s[i]=='(')
jl++;
if(s[i]==')')
{
if(jl>0)
{
jl--;
ans+=1;
}
else {
jr++;
}
}
}
p[j].l=jl;
p[j].r=jr;
}
sort(p,p+n,cp);
int le=0;
int ri=0;
for(int i=0;i<n;i++)
{
if(p[i].r>=le)
{
p[i].r-=le;
ans+=le;
le=0;
ri+=p[i].r;
le+=p[i].l;
}
else{
ans+=p[i].r;
le-=p[i].r;
le+=p[i].l;
}
}
printf("%d\n",ans*2);
}
return 0;
}
hdu 6304 Chiaki Sequence Revisited
规律
学习一下builtin 。。。。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=3e5+10;
const ll mod=1e9+7;
ll num[100],p[100];
void init(){
num[0]=p[0]=1;
for (int i=1;i<=63;i++){
num[i]=2*num[i-1]+1;
p[i]=p[i-1]*2;
}
}
ll n;
ll inv2=(mod+1)/2;
ll getsum(ll pos){
ll sum=0;
for (ll i=1;i<=pos;i*=2){
ll num=(pos-i)/(2*i);
ll Max=i+num*(2*i);
num=(num+1)%mod;
Max=(Max+i)%mod;
Max=Max*num%mod;
Max=Max*inv2%mod;
Max=Max*(__builtin_ctz(i)+1)%mod;
sum=(sum+Max)%mod;
}
return (sum+1)%mod;
}
int main(){
int t;
scanf("%d",&t);
init();
while (t--){
scanf("%lld",&n);
ll pos=0;
n--;
if (n==0){
printf("1\n");
continue;
}
ll temp=n;
for (int i=62;i>=0;i--){
if (temp>=num[i]){
temp-=num[i];
pos+=p[i];
}
}
//cout<<"pos="<<pos<<endl;
ll sum1=getsum(pos);
if (temp){
sum1=(sum1+temp%mod*(pos+1)%mod)%mod;
}
printf("%lld\n",sum1);
}
return 0;
}