2017 Multi-University Training Contest

1005 Euler theorem

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)

Problem Description
HazelFan is given two positive integers a,b, and he wants to calculate mod b. But now he forgets the value of b and only remember the value of a, please tell him the number of different possible results.
 

Input

The first line contains a positive integer T(≤ ≤ 5), denoting the number of test cases.
For each test case:
A single line contains a positive integer a(≤ ≤ 109).
 
Output
For each test case:
A single line contains a nonnegative integer, denoting the answer.
 
Sample Input
2
1
3
 
Sample Output
2
3

题意:给定正整数a,对于任意正整数b,求a mod b有多少种可能的结果

题解:签到题,可知每个小于a/2的非负整数都可以成为模的结果,当b > a时,a mod b等于a本身,因此可以计算出结果。

include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    int t,a;
    scanf("%d",&t);
    while (t--)
    {
        scanf("%d",&a);
        printf("%d
",a - (a / 2) + 1);
    }
}

1011 Kolakoski

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)

Problem Description
This is Kolakosiki sequence: 1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1,2,2,1. This sequence consists of 1 and 2, and its first term equals 1. Besides, if you see adjacent and equal terms as one group, you will get 1,22,11,2,1,22,1,22,11,2,11,22,1. Count number of terms in every group, you will get the sequence itself. Now, the sequence can be uniquely determined. Please tell HazelFan its nth element.
 
Input
The first line contains a positive integer T(≤ ≤ 5), denoting the number of test cases.
For each test case:
A single line contains a positive integer n(≤ ≤ 107).
 
Output
For each test case:
A single line contains a nonnegative integer, denoting the answer.
 
Sample Input
2
1
2
 
Sample Output
1
2
 
题意:给你一个数列1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1,2,2,1…. ,求数列的第n项
 
补充:Kolakoski序列是一个仅由1和2组成的无限数列,是一种通过“自描述”来定义的数列。它的定义很简单,若把数列中相同的数定为一组,令a(1) = 1,a(2) = 2,则a(n)等于第n组数的长度。我们可以把数列看成1,22,11,2,1,22,1,22,11,……,因此可知a(1) = 1, a(2) = 2, a(3) = 2, ……
 
题解:数列构造题,根据数列的定义来构造数列即可,用两个指针扫一下。
 
#include<iostream>
#include<cstdio>
using namespace std;
int a[10000050];
int main()
{
    int i,j,temp,k,n,t;
    a[1] = 1;
    a[2] = 2;
    a[3] = 2;
    i = 3;j = 4;temp = 1;
    while (j <= 10000050)
    {
        for (k = 1;k <= a[i];k++)
        {
            a[j] = temp;
            j++;
        }
        i++;
        temp = 3 - temp;
    }
    scanf("%d",&t);
    while (t--)
    {
        scanf("%d",&n);
        printf("%d
",a[n]);
    }
}

1008 Hard challenge

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)

 

Problem Description
There are n points on the plane, and the ith points has a value vali, and its coordinate is (xi,yi). It is guaranteed that no two points have the same coordinate, and no two points makes the line which passes them also passes the origin point. For every two points, there is a segment connecting them, and the segment has a value which equals the product of the values of the two points. Now HazelFan want to draw a line throgh the origin point but not through any given points, and he define the score is the sum of the values of all segments that the line crosses. Please tell him the maximum score.
 
Input
The first line contains a positive integer T(≤ ≤ 5), denoting the number of test cases.
For each test case:
The first line contains a positive integer n(≤ ≤ × 104).
The next n lines, the i-th line contains three integers xi,yi,vali(|xi|,|yi|109,1vali104).
 
Output
For each test case:
A single line contains a nonnegative integer, denoting the answer.
 
Sample Input
2
2
1 1 1
1 -1 1
3
1 1 1
1 -1 10
-1 0 100
 
Sample Output
1
1100
 
题意: 平面直角坐标系上有n个点,第i个点有一个点权vali,坐标(xi​​,yi​​),保证任意两点的连线不经过原点。这些点两两之间连有一条线段,线段的权值为其两端点的权值之积。作一条过原点而不过任意一个给定整点的直线,使得和这条直线相交的线段的权值和最大。
 
题解:先按照每个点极角排序,按点在x轴的左边还是右边建立一个区间,之后用尺取法每次对区间挪动一点,找出最大值即可。
 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
struct node
{
    int x,y;
    double angle;
    long long val;
};
node a[500050];
int cmp(node x,node y)
{
    return x.angle < y.angle;
}
int main()
{
    int t,n,i;
    scanf("%d",&t);
    while (t--)
    {
        scanf("%d",&n);
        for (i = 1;i <= n;i++)
        {
            scanf("%d%d%lld",&a[i].x,&a[i].y,&a[i].val);
            if (a[i].x != 0) a[i].angle = atan(1.0 * a[i].y / a[i].x);
            else a[i].angle = 3.14159265 / 2;
        }
        sort(a + 1,a + n + 1,cmp);
        long long l = 0,r = 0;
        for (i = 1;i <= n;i++)
        {
            if (a[i].x >= 0) r = r + a[i].val;
            else l = l + a[i].val;
        }
        long long ans = l * r;
        for (i = 1;i <= n;i++)
        {
            if (a[i].x >= 0)
            {
                l = l + a[i].val;
                r = r - a[i].val;
            }
            else
            {
                l = l - a[i].val;
                r = r + a[i].val;
            }
            if (l * r > ans) ans = l * r;
        }
        printf("%lld
",ans);
    } 
}

1010 Just do it

Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)

Problem Description
There is a nonnegative integer sequence a1...n of length n. HazelFan wants to do a type of transformation called prefix-XOR, which means a1...n changes into b1...n, where bi equals to the XOR value of a1,...,ai. He will repeat it for m times, please tell him the final sequence.
 
Input
The first line contains a positive integer T(≤ ≤ 5), denoting the number of test cases.
For each test case:
The first line contains two positive integers n,m(≤ ≤ × 105,≤ ≤ 109).
The second line contains n nonnegative integers a1...n(≤ a≤ 2301).
 
Output
For each test case:
A single line contains n nonnegative integers, denoting the final sequence.
 
Sample Input
2
1 1
1
3 3
1 2 3
 
Sample Output
1
1 3 1
 
题意:有一个长度为n的序列an,做m次前缀异或和(即新的序列bi = a1 xor a2 xor …… xor ai,求最终的序列
 
题解:除了官方题解的卢卡斯定理,我们还可以发现每四次变换都是有规律的,因此每四次对其进行操作
 
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
    int t,n,m,i,k;
    int a[200050];
    scanf("%d",&t);
    while (t--)
    {
        scanf("%d%d",&n,&m);
        for (i = 1;i <= n;i++) scanf("%d",&a[i]);
        k = 1;
        while (k * 4 <= m) k = k * 4;
        while (m > 0)
        {
            while (m >= k)
            {
                for (i = k + 1;i <= n;i++)
                    a[i] = a[i] ^ a[i - k];
                m = m - k;
            }
            k = k / 4;
        }
        for (i = 1;i <= n;i++)
        {
            printf("%d",a[i]);
            if (i != n) printf(" "); else printf("
");
        }
    }
}
原文地址:https://www.cnblogs.com/Suwako1997/p/7373981.html