I - Little Boxes
求四个2^62以内的数的和,由于最大的数据会爆longlong,就用py算出最大的数,然后特判了一下,赛后队友想用double试试,好像因为精度问题w了。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
int T;
cin>>T;
while(T--){
unsigned ll a,b,c,d;
cin>>a>>b>>c>>d;
if(a==(1ll<<62)&&b==(1ll<<62)&&c==(1ll<<62)&&d==(1ll<<62)){
cout<<string("18446744073709551616")<<endl;
}
else{
a+=(b+c+d);
cout<<a<<endl;
}
}
}
K - Rabbits
n 个兔子在数轴上排成一列,每次选择最左边或最右边的兔子跳到中间的一个空格位置,问最多能跳多少次。n≤500。
一道傻逼签到题,结果读错题目,三个人改了一个小时还是过不了,查了题解才发现理解错了,只有最外的两只兔子才能跳。就只要拿全部的空格减去最前或者最后较小的那一段就行了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=510;
const int inf=0x3fffffff;
int a[maxn];
int main()
{
// freopen("a.txt","r",stdin);
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
int ans=a[n]-a[2]-1-(n-3);
ans=max(a[n-1]-a[1]-1-(n-3),ans);
printf("%d\n",ans);
}
return 0;
}
L - Tree
有一颗有n个点的树,他们可以被染成k种颜色,每种颜色的点相互连起来构成一个集合,现在你要求所有集合的交集。
开始智障了,想了个假算法,先找到树的直径,然后从直径两端各选k个点,被队友举了个反例。正解是判断每条边是否可以成为交集里的边,显然只要这条边两边的点数都>=k,该边就可以成为交集里的边。只要dfs一下就行了。
#include<bits/stdc++.h>
using namespace std;
const int maxn=200010;
int t,k,ans,n;
int head[maxn],num,sz[maxn];
struct E
{
int to,next;
}edge[maxn<<1];
inline void add_edge(int u,int v)
{
edge[num].to=v;
edge[num].next=head[u];
head[u]=num++;
}
void dfs(int u,int p)
{
sz[u]=1;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(v!=p) {
dfs(v,u);
sz[u]+=sz[v];
if(sz[v]>=k&&n-sz[v]>=k) ++ans;
}
}
return;
}
int main()
{
// freopen("a.txt","r",stdin);
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
memset(head,-1,sizeof(head));
num=ans=0;
for(int i=1;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add_edge(u,v);
add_edge(v,u);
}
dfs(1,0);
printf("%d\n",ans);
}
return 0;
}
F - Heron and His Triangle
让你找到面积比n大的边长为t−1,t,t+1且面积为整数的最小的三角形。有T组数据,T≤30000,n≤10^30。
用海伦公式写了一下三角形的面积,化简了半天推不出数学公式就放弃了。查了题解才发现是打表找规律。规律为fn=4fn−1−fn−2,然后写个JAVA就好了(自己打了个表,半天也没有看出规律,orz)
import java.math.*;
import java.util.*;
import java.io.*;
public class Main
{
public static void main(String[] args)
{
Scanner cin=new Scanner(new BufferedInputStream(System.in));
BigInteger res[] = new BigInteger[100];
res[0] = BigInteger.valueOf(4L);
res[1] = BigInteger.valueOf(14L);
for (int i = 2;i < 100;i++) {
res[i] = res[i-1].multiply(new BigInteger("4")).subtract(res[i-2]);
}
while (cin.hasNext()) {
int t = cin.nextInt();
for (int ca = 1;ca <= t;ca++) {
BigInteger n = cin.nextBigInteger();
int i = 0;
for (i = 0;i < 100;i++) {
if (n.compareTo(res[i]) != 1) break;
}
System.out.println(res[i]);
}
}
cin.close();
}
}
之后有空再慢慢补剩下的题。