版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/albertluf/article/details/82228748
题目:链接
F Heron and His Triangle:
暴力跑了几发,把搞出来的数扔进oeis里发现对于条件成立的t数组
有t[i]=4*t[i-1]-t[i-2]。因此找到第一个大于等于N的t[i]就好了。
但是数值范围超过了long long,因此要用大数,这样一个个找
过去会超时,可以先对询问排序,这样下次的询问就可以接着
上次的位置寻找。
代码:
#include<bits/stdc++.h>
using namespace std;
int a[105][33],c[105],ans[30003];
int T;
char t[105];
struct node
{
int k[33],id;
}g[30003];
bool cmp(const node &x,const node &y)
{
for(int i=32;i>=0;i--)
if(x.k[i]!=y.k[i]) return x.k[i]<y.k[i];
}
void init()
{
a[0][0]=4;a[1][0]=4;a[1][1]=1;
for(int i=2;i<=100;i++)
{
int x=0;
for(int j=0;j<=32;j++)
{
a[i][j]=4*a[i-1][j]-a[i-2][j]+x;
if(a[i][j]>=0)
{
x=a[i][j]/10;
a[i][j]%=10;
}
else
{
x=-1;
a[i][j]=10+a[i][j];
}
}
}
}
bool compare(int now,int i)
{
for(int j=32;j>=0;j--)
if(a[now][j]!=g[i].k[j])
return a[now][j]>g[i].k[j];
return 1;
}
void work()
{
int now=0;
for(int i=1;i<=T;i++)
{
while(!compare(now,i)) now++;
ans[g[i].id]=now;
}
}
int main()
{
init();
scanf("%d",&T);
for(int i=1;i<=T;i++)
{
g[i].id=i;
scanf("%s",&t);
int len=strlen(t);
for(int j=0;j<len;j++)
g[i].k[j]=t[len-j-1]-'0';
}
sort(g+1,g+T+1,cmp);
work();
for(int i=1;i<=T;i++)
{
int id=ans[i],j=32;
while(a[id][j]==0) j--;
for( ;j>=0;j--) printf("%d",a[id][j]);
printf("\n");
}
return 0;
}
I Little Boxes:
大数加法:
#include<bits/stdc++.h>
using namespace std;
int a[33],b[33];
char t[33];
void add()
{
int c[33];
memset(c,0,sizeof(c));
int len=strlen(t+1);
for(int i=1;i<=len;i++) c[i]=t[len-i+1]-'0';
int k=0;
for(int i=1;i<33;i++)
{
a[i]=a[i]+c[i]+k;
k=a[i]/10;
a[i]%=10;
}
}
int main()
{
int T;scanf("%d",&T);
while(T--)
{
memset(a,0,sizeof(a));
for(int i=1;i<=4;i++)
{
scanf("%s",t+1);
add();
}
int id=32;
while(id>1&&a[id]==0) id--;
for( ;id>=1;id--) printf("%d",a[id]);
printf("\n");
}
return 0;
}
K Rabbits:
只有a[1]~a[2]或a[n-1]~a[n]跳不到,其他都能跳到。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=505;
int a[maxn];
int main()
{
int T;scanf("%d",&T);
while(T--)
{
int n;scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
int mi=min(a[2]-a[1]-1,a[n]-a[n-1]-1);
//for(int i=2;i<=n;i++) mi=min(mi,a[i]-a[i-1]-1);
printf("%d\n",a[n]-a[1]+1-n-mi);
}
return 0;
}
L Tree:
考虑一条边把整个图分成两部分,若这两部分的点的个数都大于k则这条边可行。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
vector<int>G[maxn];
int n,k,son[maxn],ans;
void dfs(int v,int fa)
{
son[v]=1;
for(int i=0;i<G[v].size();i++)
{
int to=G[v][i];
if(to==fa) continue;
dfs(to,v);
son[v]+=son[to];
if(son[to]>=k&&n-son[to]>=k) ans++;
}
}
int main()
{
int T;scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&k);
for(int i=0;i<=n;i++) G[i].clear();
ans=0;
for(int i=1;i<n;i++)
{
int x,y;scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}
dfs(1,0);
printf("%d\n",ans);
}
return 0;
}