码迷,mamicode.com
首页 > 其他好文 > 详细

山东省历届省赛No.1 思维部分

时间:2018-04-08 18:05:10      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:技术   记录   hint   contest   divide   image   lte   rom   ann   

Problem A:Rescue The Princess

Description

 

Several days ago, a beast caught a beautiful princess and the princess was put in prison. To rescue the princess, a prince who wanted to marry  the princess set out immediately. Yet, the beast set a maze. Only if the prince find out the maze’s exit can he save the princess.

Now, here comes the problem. The maze is a dimensional plane. The beast is smart, and he hidden the princess snugly. He marked two coordinates of an equilateral triangle in the maze. The two marked coordinates are A(x1,y1) and B(x2,y2). The third coordinate C(x3,y3) is the maze’s exit. If the prince can find out the exit, he can save the princess. After the prince comes into the maze, he finds out the A(x1,y1) and B(x2,y2), but he doesn’t know where the C(x3,y3) is. The prince need your help. Can you calculate the C(x3,y3) and tell him?

Input

The first line is an integer T(1 <= T <= 100) which is the number of test cases. T test cases follow. Each test case contains two coordinates A(x1,y1) and B(x2,y2), described by four floating-point numbers x1, y1, x2, y2 ( |x1|, |y1|, |x2|, |y2| <= 1000.0). 

 Please notice that A(x1,y1) and B(x2,y2) and C(x3,y3) are in an anticlockwise direction from the equilateral triangle. And coordinates A(x1,y1) and B(x2,y2) are given by anticlockwise.

Output

For each test case, you should output the coordinate of C(x3,y3), the result should be rounded to 2 decimal places in a line.

Sample Input

4
-100.00 0.00 0.00 0.00
0.00 0.00 0.00 100.00
0.00 0.00 100.00 100.00
1.00 0.00 1.866 0.50

Sample Output

(-50.00,86.60)
(-86.60,50.00)
(-36.60,136.60)
(1.00,1.00)

HINT

题意:给出A与B的坐标,要求从A到B逆时针转动位置找到一个C点,使他们组成一个等边三角形

思路:对于任意两个不同点A和B,A绕B旋转θ角度后的坐标为:(Δx*cosθ- Δy * sinθ+ xB, Δy*cosθ + Δx * sinθ+ yB ) 

代码:

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        double x1,x2,y1,y2;
        cin>>x1>>y1>>x2>>y2;
        double x=x2-x1;
        double y=y2-y1;
        double ansx=x*1/2-y*sqrt(3)/2+x1;
        double ansy=y*1/2+x*sqrt(3)/2+y1;
        printf("(%.2f,%.2f)\n",ansx,ansy);
    }

 

 

Problem F:Alice and Bob

Description

 

Alice and Bob like playing games very much.Today, they introduce a new game.

There is a polynomial like this: (a0*x^(2^0)+1) * (a1 * x^(2^1)+1)*.......*(an-1 * x^(2^(n-1))+1). Then Alice ask Bob Q questions. In the expansion of the Polynomial, Given an integer P, please tell the coefficient of the x^P.

Can you help Bob answer these questions?

 

Input

 

The first line of the input is a number T, which means the number of the test cases.

For each case, the first line contains a number n, then n numbers a0, a1, .... an-1 followed in the next line. In the third line is a number Q, and then following Q numbers P.

1 <= T <= 20

1 <= n <= 50

0 <= ai <= 100

Q <= 1000

0 <= P <= 1234567898765432

 

Output

For each question of each test case, please output the answer module 2012.

Sample Input

1
2
2 1
2
3
4

Sample Output

2
0

HINT

The expansion of the (2*x^(2^0) + 1) * (1*x^(2^1) + 1) is 1 + 2*x^1 + 1*x^2 + 2*x^3

 

题意:给定(a0*x^(2^0)+1) * (a1 * x^(2^1)+1)*.......*(an-1 * x^(2^(n-1))+1)这个式子的系数a,展开这个式子后,求x^q的系数。

思路:就是把指数转换成二进制数,再把二进制数中所有“1”的权值都加起来!! 

举个栗子:

q=3时,x^3的系数=a[1]*a[0];

q=6时,x^6的系数=a[2]*a[1];

q=7时,x^7的系数=a[2]*a[1]*a[0];

q=10时,x^10的系数=a[3]*a[1];

这些得到的系数就是题目要求的答案

代码:

int main()
{
    int a[105];
    int T;
    cin>>T;
    while(T--)
    {
        int Q,n;
        int bit[55];
        cin>>n;
        for(int i = 0; i < n; i++)
            cin>>a[i];
        cin>>Q;
        for(int i = 0; i < Q; i++)
        {
            long long p;
            cin>>p;
            int flag = 0;
            while(p){
                bit[flag] = p%2;
                p/=2;
                flag++;
            }
            if(flag>n)
                printf("0\n");
            else{
                long long flag1 = 0,answer1 = 1;
                for(int i = 0; i < flag; i++)
                {
                    if(bit[i])
                    {
                        answer1 *= a[i];
                        answer1%=2012;
                    }
                }
                printf("%d\n",answer1);
            }
        }
    }
    return 0;
}

 

 

angry_birds_again_and_again

Problem Description

The problems called "Angry Birds" and "Angry Birds Again and Again" has been solved by many teams in the series of contest in 2011 Multi-University Training Contest.
 
This time we focus on the yellow bird called Chuck. Chuck can pick up speed and distance when tapped.
 
You can assume that before tapped, Chuck flies along the parabola. When tapped, it changes to fly along the tangent line. The Chuck starts at the coordinates (0,?0). Now you are given the coordinates of the pig (Px,?0), the x-coordinate of the tapping position (Tx) and the initial flying angle of Chuck (α).
技术分享图片
∠AOx?=?α
Please calculate the area surrounded by Chuck’s path and the ground.(The area surrounded by the solid line O-Tapping position-Pig-O)

Input

The first line contains only one integer T (T is about 1000) indicates the number of test cases. For each case there are two integers, px tx, and a float number α.(0?<?Tx?≤?Px?≤?1000, 0?<?α?<? 技术分享图片) .

Output

One line for each case specifying the distance rounded to three digits.

Sample Input

1
2 1 1.0

Sample Output

0.692

题意:已知点tx、px坐标与∠AOX,求实线围成的面积。

思路:设抛物线方程为y=ax^2+bx+c;因为抛物线过原点,则c=0,又已知过原点的切线的斜率(tan(∠AOX)),对抛物线方程求导再结合点tx,可求出a,b;最后对抛物线方程从0到tx积分,再加上三角形面积。

代码:

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int tx,px;
        double R;
        scanf("%d%d%lf",&px,&tx,&R);
        double a,b,x;
        b = tan(R);
        x = tx;
        a = -b*px/(2*x*(px-tx)+x*x);
        double ans = a*x*x*x/3.0+b*x*x/2.0+(a*x*x+b*x)*(px-tx)/2.0;
        printf("%.3lf\n",ans,a,b);
    }
    return 0;
}

 

Factorial

Problem Description

Homelesser hates mathematics. He cannot even do addition and subtraction, not to mention computing factorial. He asks Cainiao2hao for help. Cainiao2hao is always busy solving more difficult problems. And now, please help Homelesser to compute factorial. If you cannot do it well, Cainiao2hao will think you are as fool as Homelesser.
 

Input

The first line contains only one integer T (T is about 10) indicates the number of test cases. For each case there are one integer n (0?≤?n?≤?10).
 

Output

One line for each case specifying the factorial of n.
 

Sample Input

2
4
3

Sample Output

24
6

题意:求阶乘
代码:
int main()
{
    IO;
    int T;
    cin>>T;
    while(T--)
    {
        int n;
        cin>>n;
        LL ans=1;
        for(int i=2;i<=n;i++)
        ans*=i;
        cout<<ans<<endl;
    }
    return 0;
}

 


Full Binary Tree

Problem Description

In computer science, a binary tree is a tree data structure in which each node has at most two children. Consider an infinite full binary tree (each node has two children except the leaf nodes) defined as follows. For a node labelled v its left child will be labelled 2?*?v and its right child will be labelled 2?*?v?+?1. The root is labelled as 1.
 
You are given n queries of the form i,?j. For each query, you have to print the length of the shortest path between node labelled i and node labelled j.
 

Input

First line contains n(1?≤?n?≤?10^5), the number of queries. Each query consists of two space separated integers i and j(1?≤?i,?j?≤?10^9) in one line.
 

Output

For each query, print the required answer in one line.
 

Sample Input

5
1 2
2 3
4 3
1024 2048
3214567 9998877

Sample Output

1
2
3
1
44

题意:

一个满二叉树,给你两个节点,求出这两个节点间的长度.
简单来说要先找到两个节点的最近的公共祖先.这样经过的路程才是可求的最短的路径.现在已知两个节点,只需不停的最大数除以二,直到a==b,这个时候表示已经达到最近的公共祖先.每次除的时候,ans+1,记录路径的长度.最后当a==b时,所求的即为俩个节点间的距离.

代码:

int main()
{
    IO;
    int T;
    cin>>T;
    while(T--)
    {
        LL n,m;
        cin>>n>>m;
        LL sum=0;
        while(1)
        {
            if(n>m)
            {
                n/=2;
                sum++;
            }
            if(n==m)
                break;
            if(n<m)
            {
                m/=2;
                sum++;
            }
            if(n==m)
                break;
        }
    cout<<sum<<endl;
    }
    return 0;

 

Weighted Median

Problem Description

For n elements x1,?x2,?...,?xn with positive integer weights w1,?w2,?...,?wn. The weighted median is the element xk satisfying
技术分享图片 and 技术分享图片 , S indicates 技术分享图片
Can you compute the weighted median in O(n) worst-case?
 

Input

There are several test cases. For each case, the first line contains one integer n(1?≤??n?≤?10^7) — the number of elements in the sequence. The following line contains n integer numbers xi (0?≤?xi?≤?10^9). The last line contains n integer numbers wi (0?<?wi?<?10^9).
 

Output

One line for each case, print a single integer number— the weighted median of the sequence.
 

Sample Input

7
10 35 5 10 15 5 20
10 35 5 10 15 5 20

Sample Output

20

Hint

The S which indicates the sum of all weights may be exceed a 32-bit integer. If S is 5, 技术分享图片 equals 2.5.
 
题目意思:
给一些数x和它们对应的权值w,按照如图所示公式,s是所有权值w的总和。
求一个xk,使得满足前两个公式。

解题思路:
用结构体保存元素值和权值,先升序排列,累计xk之前的权值和,直到该权值大于s。
struct node
{
    LL number;
    LL weight;
} nodee[10000000];
bool cmp(node a,node b)
{
    return a.number<b.number;
}
int main()
{
    IO;
    int n;
    while(cin>>n)
    {
        LL sum=0;
        for(int i=0; i<n; i++)
        {
            cin>>nodee[i].number;
        }
        for(int i=0; i<n; i++)
        {
            cin>>nodee[i].weight;
            sum+=nodee[i].weight;
        }
        sort(nodee,nodee+n,cmp);
        sum=sum;
        LL sum1=0,sum2=0;
        int logo=0;
        for(int i=0; i<n; i++)
        {
            sum1+=nodee[i].weight;
            sum2=sum-sum1-nodee[i+1].weight;
            if(sum1<sum/2&&sum2<=sum/2)
            {
                logo=i;
                break;
            }
        }
        cout<<nodee[logo+1].number<<endl;
    }
    return 0;
}

 

Nias and Tug-of-War

Problem Description

Nias is fond of tug-of-war. One day, he organized a tug-of-war game and invited a group of friends to take part in.

Nias will divide them into two groups. The strategy is simple, sorting them into a row according to their height from short to tall, then let them say one and two alternately (i.e. one, two, one, two...). The people who say one are the members of the red team while others are the members of the blue team.

We know that the team which has a larger sum of weight has advantages in the tug-of-war. Now give you the guys‘ heights and weights, please tell us which team has advantages.

Input

The first line of input contains an integer T, indicating the number of test cases.

The first line of each test case contains an integer N (N is even and 6 ≤ N ≤ 100). 

Each of the next N lines contains two real numbers X and Y, representing the height and weight of a friend respectively.

Output

One line for each test case. If the red team is more likely to win, output "red", if the blue team is more likely to win, output "blue". If both teams have the same weight, output "fair".

Sample Input

1
6 
170 55 
165.3 52.5 
180.2 60.3 
173.3 62.3 
175 57 
162.2 50

Sample Output

blue

题意:按照身高排序,然后单数一组,双数一组,问哪个组体重大。

1.注意先排序

2.如果身高体重用不同的数组注意对另一个数组排序

int main()
{
    IO;
    int T;
    cin>>T;
    while(T--)
    {
        int n;
        cin>>n;
        for(int i=0; i<n; i++)
        {
            cin>>nodee[i].high>>nodee[i].weight;
        }
        sort(nodee,nodee+n,cmp);
        double sum1=0;
        double sum2=0;
        for(int i=0; i<n; i++)
        {
            if(i%2==0)
                sum1+=nodee[i].weight;
            else
                sum2+=nodee[i].weight;
        }
        if(sum1>sum2)
            cout<<"red"<<endl;
        else if(sum1<sum2)
            cout<<"blue"<<endl;
        else
            cout<<"fair"<<endl;
    }
    return 0;
}

Game!

Problem Description

One day, zbybr is playing a game with blankcqk, here are the rules of the game:

There is a circle of N stones, zbybr and blankcqk take turns taking the stones.

Each time, one player can choose to take one stone or take two adjacent stones.

You should notice that if there are 4 stones, and zbybr takes the 2nd, the 1st and 3rd stones are still not adjacent.

The winner is the one who takes the last stone.

Now, the game begins and zbybr moves first.

 

If both of them will play with the best strategy, can you tell me who will win the game?

Input

The first line of input contains an integer T, indicating the number of test cases (T≈100000).

For each case, there is a positive integer N (N ≤ 10^18).

Output

Output the name of the winner.

Sample Input

2
1
2

Sample Output

zbybr
zbybr

题意:zbybr先手,谁将环形石子最后一个拿走谁赢

对于环形的博弈,先手只可能在他能拿石子个数的范围内取胜,否则后手赢。因为当石子个数大于先手能拿的个数,若先手拿完后,剩下奇数个后手拿与先手对应位置的石子
即可,为偶则拿对应的两个,总可以让先手输
int main()
{
    IO;
    int T;
    cin>>T;
    while(T--)
    {
        long long  n;
        cin>>n;
        if(n==1||n==2)
            cout<<"zbybr"<<endl;
        else
            cout<<"blankcqk"<<endl;
    }
    return 0;
}
 

Single Round Math

Problem Description

Association for Couples Math (ACM) is a non-profit organization which is engaged in helping single people to find his/her other half. As November 11th is “Single Day”, on this day, ACM invites a large group of singles to the party. People round together, chatting with others, and matching partners.

There are N gentlemen and M ladies in the party, each gentleman should only match with a lady and vice versa. To memorize the Singles Day, ACM decides to divides to divide people into 11 groups, each group should have the same amount of couples and no people are left without the groups.

Can ACM achieve the goal?

Input

The first line of the input is a positive integer T. T is the number of test cases followed. Each test case contains two integer N and M (0 ≤ N, M ≤ 10^1000), which are the amount of gentlemen and ladies.

Output

For each test case, output “YES” if it is possible to find a way, output “NO” if not.

Sample Input

3
1 1
11 11
22 11

Sample Output

NO
YES
NO

题意:
给定n个绅士和m个美女,要求能把他们分成11对,每对一男一女。
思路:大数模拟或者java或者每次对11取余
代码:
int main()
{
    IO;
    int T;
    cin>>T;
    while(T--)
    {
        char n[100000];
        char m[100000];
        cin>>n>>m;
        if(strcmp(n,m)!=0)
            cout<<"NO"<<endl;
        else
        {
            int sum=0;
            for(int i=0;i<strlen(n);i++)
            {
                sum=(sum*10+n[i]-48)%11;
            }
            if(sum==0)
                cout<<"YES"<<endl;
            else
                cout<<"NO"<<endl;
        }
    }
    return 0;
}

 

山东省历届省赛No.1 思维部分

标签:技术   记录   hint   contest   divide   image   lte   rom   ann   

原文地址:https://www.cnblogs.com/aiguona/p/8745866.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!