Maximum Multiple
n=x+y+z,x|n,y|n,z|n;
n=t1*x,n=t2*y,n=t3*z;
1/t1+1/t2+1/t3=1;
假设t1>=t2>=t3;
解的:有三组解 1、2,4,4; 2、3,3,3;3、 2,3,6;
因为要求x*y*z的最大值,所以第三组解明显比第二组解小,所以第三个答案舍弃
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string>
#include<string.h>
using namespace std;
const int maxn=1e6+7;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
long long m;
if(n%3==0)
{
m=(long long)n/3*(long long)n/3*(long long)n/3;
printf("%lld\n",m);
}
else if(n%4==0)
{
m=(long long)n/2*(long long)n/4*(long long)n/4;
printf("%lld\n",m);
}
else
{
printf("-1\n");
}
}
}
Balanced Sequence
给你n个括号的字符串,这n个字符串连接以后最多有多少个匹配的半括号,匹配的括号可以不连续
例如:)()(()( 结果为4
可以先将每个字符串中的已经匹配好的括号挑出来,所有的字符串都变成"))))",")))(((","(((",这三种形式
两个字符串排序a,b; (a排在b前面)x=min(a.l,b.r),(b排在a前面)y=min(a.r,b.l);可以匹配的括号数量,如果x>y
则a放在前面,若x<y则b放前面,若x=y,则右边括号少的放前面
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string>
#include<string.h>
#include<stack>
using namespace std;
const int maxn=1e5+7;
char str[maxn];
struct node
{
int l,r;
} s[maxn];
bool cmp(node a,node b)
{
int aa=min(a.l,b.r);
int bb=min(a.r,b.l);
if(aa==bb)
return a.l>b.l;
return aa>bb;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int ans=0;
int n;
scanf("%d",&n);
for(int i=0; i<n; i++)
{
scanf("%s",str);
s[i].l=s[i].r=0;
for(int j=0; str[j]!='\0'; j++)
{
if(str[j]=='(')
s[i].l++;
else
{
if(s[i].l)
{
s[i].l--;
ans+=2;
}
else
s[i].r++;
}
}
}
sort(s,s+n,cmp);
int l=0,r=0;
for(int i=0; i<n; i++)
{
if(s[i].r>l)
{
ans+=2*l;
l=0;
}
else
{
ans+=s[i].r*2;
l-=s[i].r;
}
l+=s[i].l;
}
printf("%d\n",ans);
}
}
Triangle Partition
总共有3n个点,输出n行(a,b,c);a,b,c为可以构成三角形的点的编号,这n个三角形不相交(输出一种结果即可)
按照x轴排个序,如果x轴相同,按y轴排个序,按顺序输出即可
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string>
#include<string.h>
#include<stack>
using namespace std;
const int maxn=1e5+7;
struct node
{
int x,y,id;
}p[3003];
bool cmp(node a,node b)
{
if(a.x==b.x)
return a.y<b.y;
return a.x<b.x;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=3*n;i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
p[i].id=i;
}
sort(p+1,p+3*n+1,cmp);
for(int i=1;i<=3*n;i++)
{
if(i%3)printf("%d ",p[i].id);
else printf("%d\n",p[i].id);
}
}
}
Chiaki Sequence Revisited
求;
先打表:a[1]=1,a[2]=1,a[n]=a[n-a[n-1]]+a[n-1-a[n-2]];
1 1 2 2 3 4 4 4 5 6 6 7 8 8 8 8 9 10 10 11 12 12 12 13 14 14 15 16 16 16
16 16 17 18 18 19 20 20 20 21 22 22 23 24 24 24 24 25 26 26 27 28 28 28 29 30 30 31 32 32
32 32 32 32 33 34 34 35 36 36 36 37 38 38 39 40 40 40 40 41 42 42 43 44 44 44 45 46 46 47
48 48 48 48 48 49 50 50 51 52 52 52 53 54 54 55 56 56 56 56 57 58 58 59 60 60 60 61 62 62
63 64 64 64 64 64 64 64 65 66 66 67 68 68 68 69 70 70 71 72 72 72 72 73 74 74 75
每个数字出现的次数
2 2 1 3 1 2 1 4 1 2 1 3 1 2 1 5 1 2 1 3 1 2 1 4 1 2 1 3 1 2
1 6 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 5 1 2 1 3 1 2 1 4 1 2 1 3
1 2 1 7 1 2 1 3 1 2 1 4 1 2 1
除去第一项,可以发现数字出现次数的规律为
前2^i项数字出现的次数和等于前2^(i-1)项数字出现的次数和*2+1;
还可以发现
1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37…………
2 6 10 14 18 22 26 30 34 …………
4 12 20…………
…………
为首项2^i,公差为2^(i+1)次方的等差数列
计算出数组a a[i]表示前2^i次方项数字出现次数的和 a[i]=2*a[i-1]+1;
求前n项的an的和,先求出第n项在数字出现次数数列里的位置
因为是从规律是从第二项开始n--;
计算出完整前n项在数字出现次数的值sum,剩余的项数的数量为tmp,对应的值为sum+1
for(int i=62; i>=0; i--)
{
if(tmp>=a[i])
{
tmp-=a[i];
sum+=f[i];
}
}
求出完整的对应的结果,最后结果加上第一项,求等差数列的和时除以2用逆元,否则会爆掉
int getnum(ll x)///出现的次数
{
return lower_bound(f,f+63,x)-f+1;
}
ll solve(ll x)
{
ll ans=0;
for(ll i=1; i<=x; i=2*i)
{
ll num=(x-i)/(2*i);///公差
ll an=i+num*(2*i);///末项
num=(num+1)%mod;///项数
ll res=(((i+an)%mod*num)%mod*inv)%mod;///等差数列和
ans=(ans+res*getnum(i)%mod)%mod;
}
return (ans+1)%mod;
}
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string>
#include<string.h>
#include<stack>
#include<queue>
typedef long long ll;
using namespace std;
ll a[105],f[105];
const ll mod=1e9+7;
const ll inv=(mod+1)/2;
void init()
{
a[0]=f[0]=1;
for(int i=1; i<=62; i++)
{
f[i]=2*f[i-1];
a[i]=2*a[i-1]+1;
}
}
int getnum(ll x)
{
return lower_bound(f,f+63,x)-f+1;
}
ll solve(ll x)
{
ll ans=0;
for(ll i=1; i<=x; i=2*i)
{
ll num=(x-i)/(2*i);
ll an=i+num*(2*i);
num=(num+1)%mod;
ll res=(((i+an)%mod*num)%mod*inv)%mod;
ans=(ans+res*getnum(i)%mod)%mod;
}
return (ans+1)%mod;
}
int main()
{
int t;
scanf("%d",&t);
init();
while(t--)
{
ll n;
scanf("%lld",&n);
if(n==1)
printf("%lld\n",n);
else
{
n--;
ll sum=0,tmp=n;
for(int i=62; i>=0; i--)
{
if(tmp>=a[i])
{
tmp-=a[i];
sum+=f[i];
}
}
ll ans=solve(sum);
if(tmp)
{
ans=(ans+tmp*(sum+1))%mod;
}
printf("%lld\n",ans);
}
}
}
Time Zone
给你UTF+8的时间,求UTFx.y(x)的时间(-14<=x,x.y<=14,0<=y<=9)
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string>
#include<string.h>
#include<stack>
#include<queue>
using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int a,b;
char s[10];
scanf("%d %d %s",&a,&b,s);
int len=strlen(s);
int f=0;
int num1=0,num2=0;
a=((a+24)-8)%24;
for(int i=0;i<len;i++)
{
if(s[i]=='.')
f=i;
}
if(f)
{
if(f==6)
num1+=((s[4]-'0')*10+(s[5]-'0')),num2+=(s[7]-'0')*6;
else
num1+=(s[4]-'0'),num2+=(s[6]-'0')*6;
}
else
{
if(len==6)
num1+=((s[4]-'0')*10+(s[5]-'0'));
else
num1+=(s[4]-'0');
}
if(s[3]=='+')
{
b+=num2;
a+=b/60;
b=b%60;
a=(a+num1)%24;
}
else
{
a--;
a=(a+24)%24;
b=b+60-num2;
a+=b/60;
b=b%60;
a=((a+24)-num1)%24;
}
printf("%02d:%02d\n",a,b);
}
}