没想到容斥原理,一开始想使用线性筛晒出符合条件的数字,然后超内存。之后尝试想到容斥原理,当时容斥原理不会枚举两辆数字相乘,三三数字相乘这些情况所以没写。代码能力还是太弱了。
这个赛后看题解补完了。
#include<bits/stdc++.h>
using namespace std;
int main() {
int A,B;
cin>>A>>B;
double sum1=4*A*A-8*(A*A-B);
if(sum1>=0) {
double ans1=(2*A+sqrt(sum1))/4,ans2=(2*A-sqrt(sum1))/4;
printf("%.2lf %.2lf\n",min(ans1,ans2),max(ans1,ans2));
} else
puts("No Answer");
return 0;
}
函数f可以枚举几项后找出规律,发现为斐波那契数列。N皇后问题由于最多只有13,所以打表解决,至于如何判定是否为斐波那契数,由于符合x范围的只存在前90项,所以枚举查找即可得出答案。至于如何求取m进制下n!末尾0的个数,CodeForce上有过原题,转载一下
#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int MAXN=101;
int num[20];
long long num1[MAXN];
void init() {
num[1]=1,num[2]=0,num[3]=0;
num[4]=2,num[5]=10,num[6]=4;
num[7]=40,num[8]=92,num[9]=352;
num[10]=724,num[11]=2680,num[12]=14200,num[13]=73712;
num1[1]=1,num1[2]=1;
for(int i=3;i<=88;i++)
num1[i]=num1[i-1]+num1[i-2];
}
int main() {
init();
long long x,m;
cin>>x>>m;
bool flag=false;
for(int i=1;i<=88;i++) {
if(x==num1[i]) {
flag=true;
break;
}
}
if(flag) {
long long ans=1e18,sum1=0,sum2=0;
for(int i=2;i<=100;i++) {
if(m%i)
continue;
sum1=sum2=0;
//sum1记录m中包含质因数i的个数
while(m%i==0)
sum1++,m/=i;
long long temp=x;
//sum2记录x!中包含质因数i的个数
while(temp) {
sum2+=temp/i;
temp/=i;
}
//由于求解在m进制下最小的质因数的个数,所以x!中包含的
//质因数的数目需要减去m中包含的质因数的数目
//最后的结果才是答案
ans=min(ans,sum2/sum1);
}
printf("%lld\n",ans);
} else
cout<<num[x%min((long long)13,m)+1]<<endl;
return 0;
}
纯粹考虑代码能力的一道题目,分块的思想。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll func(ll n,ll c){
ll b=((n/c)*((n/c)-1))/2*c;
return b+(n%c+1ll)*(n/c);
}
int main(){
ll n, k=5, ans=0;
scanf("%lld",&n);
while((n/k)>=1)
ans+=func(n, k),k*=5ll;
printf("%lld\n",ans);
return 0;
}
这个果断OESQ上找出序列然后直接抄一波结论得出答案啦。(不过同样代码第一发竟然会WA就很迷,之后倒是对了)
#include<bits/stdc++.h>
int main()
{
long long n;
while(~scanf("%lld",&n)) {
long long ans=(n*n*n*n - 6*n*n*n + 23*n*n - 18*n + 24)/24;
printf("%lld\n",ans);
}
return 0;
}
发现样例中的数字是斐波那契数列,同时斐波那契数列中数字为偶数不吃,奇数直接吃,那就盲猜一波结论然后莽一发吧然后就过了......
#include<bits/stdc++.h>
using namespace std;
int main() {
long long n;
while(~scanf("%lld",&n)) {
long long ans1=n/3*2,ans2=n%3;
printf("%lld\n",ans1+ans2);
}
return 0;
}
真签到题
#include<bits/stdc++.h>
using namespace std;
int main() {
unsigned long long a,b;
cin>>a>>b;
unsigned long long c=__gcd(a,b);
cout<<(a/c)*b<<endl;
return 0;
}
看到区间问题---线段树线段树。然后MLE,树状数组树状数组,然后AC。当然正解是前缀和啦。前缀和
树状数组
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 1000101;
ll c1[MAXN],c2[MAXN],num[MAXN];
int n,m;
ll lowbit(ll x)
{
return (x & (-x));
}
ll sigma(ll a[],ll pos)
{
ll ans = 0;
while(pos)
{
ans += a[pos];
pos -= lowbit(pos);
}
return ans;
}
void add(ll a[],int pos, ll num)
{
while(pos < MAXN)
{
a[pos] += num;
pos += lowbit(pos);
}
return ;
}
int main()
{
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i++)
{
scanf("%lld",&num[i]);
add(c1,i,num[i] - num[i-1]);
add(c2,i,(i-1)*(num[i]-num[i-1]));
}
//首先进行区间的更新操作
ll q,l,r,v;
for(int i = 1;i <= m;i++)
{
scanf("%lld%lld%lld%lld",&q,&l,&r,&v);
if(q==1) v=-v;
add(c1,l,v);add(c1,r+1,-v);
add(c2,l,v*(l-1));add(c2,r+1,-v*r);
}
//然后进行区间求和操作
scanf("%lld%lld",&l,&r);
ll sum1 = (l-1)*sigma(c1,l-1) - sigma(c2,l-1);
ll sum2 = r *sigma(c1,r) - sigma(c2,r);
printf("%lld\n",sum2 - sum1);
}
前缀和
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1000000;
int n,m,q,l,r,p;
int x[MAXN+11];
int c[MAXN+11];
int main()
{
while(~scanf("%d%d",&n,&m)) {
memset(c,0,sizeof(c));
for(int i=1;i<=n;i++)
scanf("%d",&x[i]);
for(int i=1;i<=m;i++) {
scanf("%d%d%d%d",&q,&l,&r,&p);
if(q!=1)
c[l]+=p,c[r+1]-=p;
else
c[l]-=p,c[r+1]+=p;
}
for(int i=1;i<=n;i++)
c[i]+=c[i-1];
scanf("%d%d",&l,&r);
long long sum=0;
for(int i=l;i<=r;i++)
sum=sum+x[i]+c[i];
printf("%lld\n",sum);
}
return 0;
}
又一道签到题。
#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
struct node{
int hour,mintue;
int sum;
};
vector<node> p;
void init() {
node temp;
temp.hour=0,temp.mintue=0;
temp.sum=temp.hour*60+temp.mintue;
p.push_back(temp);
temp.hour=1,temp.mintue=10;
temp.sum=temp.hour*60+temp.mintue;
p.push_back(temp);
temp.hour=2,temp.mintue=20;
temp.sum=temp.hour*60+temp.mintue;
p.push_back(temp);
temp.hour=3,temp.mintue=30;
temp.sum=temp.hour*60+temp.mintue;
p.push_back(temp);
temp.hour=4,temp.mintue=40;
temp.sum=temp.hour*60+temp.mintue;
p.push_back(temp);
temp.hour=5,temp.mintue=50;
temp.sum=temp.hour*60+temp.mintue;
p.push_back(temp);
temp.hour=10,temp.mintue=1;
temp.sum=temp.hour*60+temp.mintue;
p.push_back(temp);
temp.hour=11,temp.mintue=11;
temp.sum=temp.hour*60+temp.mintue;
p.push_back(temp);
temp.hour=12,temp.mintue=21;
temp.sum=temp.hour*60+temp.mintue;
p.push_back(temp);
temp.hour=13,temp.mintue=31;
temp.sum=temp.hour*60+temp.mintue;
p.push_back(temp);
temp.hour=14,temp.mintue=41;
temp.sum=temp.hour*60+temp.mintue;
p.push_back(temp);
temp.hour=15,temp.mintue=51;
temp.sum=temp.hour*60+temp.mintue;
p.push_back(temp);
temp.hour=20,temp.mintue=2;
temp.sum=temp.hour*60+temp.mintue;
p.push_back(temp);
temp.hour=21,temp.mintue=12;
temp.sum=temp.hour*60+temp.mintue;
p.push_back(temp);
temp.hour=22,temp.mintue=22;
temp.sum=temp.hour*60+temp.mintue;
p.push_back(temp);
temp.hour=23,temp.mintue=32;
temp.sum=temp.hour*60+temp.mintue;
p.push_back(temp);
temp.hour=0,temp.mintue=0;
temp.sum=24*60;
p.push_back(temp);
}
int main() {
init();
int temp1,temp2;
scanf("%d:%d",&temp1,&temp2);
if(temp1==0&&temp2==0) {
puts("23:32");
puts("1:10");
return 0;
} else {
int sum1=temp1*60+temp2;
int min1=inf,ans=0;
for(int i=0;i<p.size();i++) {
if(p[i].sum<sum1) {
if((sum1-p[i].sum)<min1)
min1=sum1-p[i].sum,ans=i;
} else
break;
}
cout<<p[ans].hour<<":"<<p[ans].mintue<<endl;
for(int i=0;i<p.size();i++) {
if(p[i].sum>sum1) {
cout<<p[i].hour<<":"<<p[i].mintue<<endl;
break;
}
}
}
return 0;
}