ACM暑期集训33

组队训练赛第五场

A - BBP Formula

题目连接 传送门

分析:
BBP算法的模板 用来直接计算π的第n+1,n+2...十六进制位

详细算法证明见 传送门

 

#include <iostream>
#include <cmath>
#include <stdio.h>
using namespace std;

typedef long long ll;

ll qpower(ll a, ll b, ll mod)
{
        ll res = 1;
        while(b)
        {
            if(b & 1) res = a * res % mod;
            b >>= 1;
            a = a * a % mod;
        }
        return res;
}

double bbp(int n,ll k,ll b)
{
	double res=0;
	for(int i=0;i<=n;i++)
	{
		res+=(qpower(16,n-i,8*i+b)*1.0/(8*i+b));
	}

	for(int i=n+1;i<=n+1001;i++)
	{
		res+=(powf(16,n-i)*1.0/(8*i+b));
	}
	return k*res;
}

int main()
{
    int t,n;
    scanf("%d",&t);
    for(int i=1;i<=t;i++)
	{
		double ans=0;
		scanf("%d",&n);
		n--;
		ans = bbp(n,4,1) - bbp(n,2,4) - bbp(n,1,5) - bbp(n,1,6);
		ans=ans-(int)ans;
		if(ans<0) ans+=1;
		ans*=16;
		int j=ans;
		if(j>=0&&j<=9) printf("Case #%d: %d %c\n",i,n+1,(char)(j+'0'));
		else printf("Case #%d: %d %c\n",i,n+1,(char)(j+55));
	}
    return 0;
}

 

Little boxes on the hillside. 
Little boxes made of ticky-tacky. 
Little boxes. 
Little boxes. 
Little boxes all the same. 
There are a green boxes, and b pink boxes. 
And c blue boxes and d yellow boxes. 
And they are all made out of ticky-tacky. 
And they all look just the same. 

Input

The input has several test cases. The first line contains the integer t (1 ≤ t ≤ 10) which is the total number of test cases. 
For each test case, a line contains four non-negative integers a, b, c and d where a, b, c, d ≤ 2^62, indicating the numbers of green boxes, pink boxes, blue boxes and yellow boxes. 

Output

For each test case, output a line with the total number of boxes. 

Sample Input

4
1 2 3 4
0 0 0 0
1 0 0 0
111 222 333 404

Sample Output

10
0
1
1070

分析:

这个就考unsigned long long 的范围了,他是2^64-1,也就是a,b,c,d都取上界是他们之和小1,需另行讨论这种情况


#include<iostream>
#include<stdio.h>
#include<string.h>
#include <cmath>
using namespace std;

int main()
{
    int t;
    unsigned long long a[4];
    unsigned long long v=pow(2,62);
    scanf("%d",&t);
    while(t--)
    {
        int vis=0;
        unsigned long long sum=0;
        for(int i=0;i<4;i++){
            scanf("%llu",&a[i]);
            sum+=a[i];
        }
        for(int i=0;i<4;i++)
            if(a[i]!=v){
                vis=1;
                break;
            }
        if(vis)printf("%llu\n",sum);
        else printf("18446744073709551616\n");
    }
    return 0;
}

 

K - Rabbits

 

Here N (N ≥ 3) rabbits are playing by the river. They are playing on a number line, each occupying a different integer. In a single move, one of the outer rabbits jumps into a space between any other two. At no point may two rabbits occupy the same position. 
Help them play as long as possible

Input

The input has several test cases. The first line of input contains an integer t (1 ≤ t ≤ 500) indicating the number of test cases. 
For each case the first line contains the integer N (3 ≤ N ≤ 500) described as above. The second line contains n integers a1a1 < a2a2 < a3a3 < ... < aNaN which are the initial positions of the rabbits. For each rabbit, its initial position 
aiai satisfies 1 ≤ aiai ≤ 10000. 

Output

For each case, output the largest number of moves the rabbits can make. 

Sample Input

5
3
3 4 6
3
2 3 5
3
3 5 9
4
1 2 3 4
4
1 2 4 5

Sample Output

1
1
3
0
1

 

 

一开始,边上间隔小的那个兔子跳到里面,并且贴到边上;

然后每次都这样做;

答案为sigma(距离和)-  最开始边上小的距离;

 

#include <iostream>
#include <cmath>
#include <stdio.h>
using namespace std;
int s[505];
int main()
{
    int T,n;
    cin>>T;
    for(int t=1;t<=T;t++){
        scanf("%d",&n);
        int ans=0;
        for(int i=0;i<n;i++){
                scanf("%d",&s[i]);
                if(i)ans+=s[i]-s[i-1]-1;
        }
        int a=s[1]-s[0],b=s[n-1]-s[n-2];
        ans-=min(a,b)-1;
        printf("%d\n",ans);
    }
    return 0;
}

 

L - Tree

Consider a un-rooted tree T which is not the biological significance of tree or plant, but a tree as an undirected graph in graph theory with n nodes, labelled from 1 to n. If you cannot understand the concept of a tree here, please omit this problem. 
Now we decide to colour its nodes with k distinct colours, labelled from 1 to k. Then for each colour i = 1, 2, · · · , k, define Ei as the minimum subset of edges connecting all nodes coloured by i. If there is no node of the tree coloured by a specified colour i, Ei will be empty. 
Try to decide a colour scheme to maximize the size of E1 ∩ E2 · · · ∩ Ek, and output its size.

Input

The first line of input contains an integer T (1 ≤ T ≤ 1000), indicating the total number of test cases. 
For each case, the first line contains two positive integers n which is the size of the tree and k (k ≤ 500) which is the number of colours. Each of the following n - 1 lines contains two integers x and y describing an edge between them. We are sure that the given graph is a tree. 
The summation of n in input is smaller than or equal to 200000. 

Output

For each test case, output the maximum size of E1 ∩ E1 ... ∩ Ek.

Sample Input

3
4 2
1 2
2 3
3 4
4 2
1 2
1 3
1 4
6 3
1 2
2 3
3 4
3 5
6 2

Sample Output

1
0
1

分析;

如果有一条边,他的左边有不小于K的结点,他的右边也有不小于K的结点,那么,两边各图K种颜色,剩下的随意,这样的边一定符合题意

 

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<math.h>
#include<string.h>

using namespace std;
const int maxn=2e5+10;

struct node
{
    int u,v;
    int next;
}e[2*maxn];
int head[maxn];
int ans[maxn];
int cnt,n,k,tot;

void add(int u,int v)
{
    e[cnt].u=u;
    e[cnt].v=v;
    e[cnt].next=head[u];
    head[u]=cnt;
    cnt++;
}

int dfs(int son,int fa)
{
    ans[son]=1;
    for(int i=head[son];i!=-1;i=e[i].next)
    {
        int to=e[i].v;
        if(to==fa) continue;
        dfs(to,son);
        ans[son]+=ans[to];
    }
    if(ans[son]>=k&&n-ans[son]>=k) tot++;
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        cnt=0,tot=0;
        memset(head,-1,sizeof(head));
        scanf("%d%d",&n,&k);
        for(int i=1;i<n;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            add(a,b);
            add(b,a);
        }
        memset(ans,0,sizeof(ans));
        dfs(1,-1);
        printf("%d\n",tot);
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值