春季训练个人赛 -2

1、 Height Ordering

Mrs. Chambers always has her class line up in height order (shortest at the front of the line). Every
September a new class of exactly 20 3rd graders arrive, all of different height. For the first few days it
takes a long time to get the kids in height order, since no one knows where they should be in the line.
Needless to say, there is quite a bit of jockeying around. This year Mrs. Chambers decided to try a new
method to minimize this ordering chaos. One student would be selected to be the first person in line.
Then, another student is selected and would find the first person in the line that is taller than him, and
stand in front of that person, thereby causing all the students behind him to step back to make room.
If there is no student that is taller, then he would stand at the end of the line. This process continues,
one student at-a-time, until all the students are in line, at which point the students will be lined up in
height order.
For this problem, you will write a program that calculates the total number of steps taken back
during the ordering process for a given class of students.

Input
The first line of input contains a single integer P, (1 ≤ P ≤ 1000), which is the number of data sets
that follow. Each data set should be processed identically and independently.
Each data set consists of a single line of input. It contains the data set number, K, followed by
20 non-negative unique integers separated by a single space. The 20 integers represent the height (in
millimeters) of each student in the class.

Output
For each data set there is one line of output. The single output line consists of the data set number,
K, followed by a single space followed by total number of steps taken back.

Sample Input
4
1 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919
2 919 918 917 916 915 914 913 912 911 910 909 908 907 906 905 904 903 902 901 900
3 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 900
4 918 917 916 915 914 913 912 911 910 909 908 907 906 905 904 903 902 901 900 919

Sample Output
1 0
2 190
3 19
4 171

题意:对 12 个同学的身高进行比较排序,如果前一同学身高高于该同学,则进行移动,求移动的总数目
CODE:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
typedef long long LL;
using namespace std;
//#define memset(a,n) memset(a,n,sizeof(a))
#define INF 0x3f3f3f3f

int main()
{
    int t,k;
    int a[22];
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&k);
        for(int i=0;i<20;i++)
            scanf("%d",&a[i]);

        int sum=0;
        for(int i=0;i<20;i++){
            for(int j=i+1;j<20;j++){
                if(a[i]>a[j])
                    sum++;
            }
        }

        cout<<k<<' '<<sum<<endl;
    }
}

2、 Islands in the Data Stream

Given a sequence of integers a1, a2, a3, …, an, an island in the sequence is a contiguous subsequence for
which each element is greater than the elements immediately before and after the subsequence. In the
examples below, each island in the sequence has a bracket below it. The bracket for an island contained
within another island is below the bracket of the containing island.
Write a program that takes as input a sequence of 12 non-negative integers and outputs the number
of islands in the sequence.
在这里插入图片描述
Input
The first line of input contains a single integer P, (1 ≤ P ≤ 1000), which is the number of data sets
that follow. Each data set should be processed identically and independently.
Each data set consists of a single line of input. It contains the data set number, K, followed by 12
non-negative integers separated by a single space. The first and last integers in the sequence will be ‘0’.
Output
For each data set there is one line of output. The single output line consists of the data set number,
K, followed by a single space followed by the number of islands in the sequence.
Sample Input
4
1 0 0 1 1 2 2 1 1 0 1 2 0
2 0 1 2 4 3 1 3 4 5 2 1 0
3 0 1 2 4 4 1 0 2 4 1 0 0
4 0 1 2 3 4 5 6 7 8 9 10 0
Sample Output
1 4
2 8
3 6
4 10

题意:
如果满足此下条件:该字符串中的所有数字都比左右相邻的数字大
求满足此条件的字符串的个数
已知第一个和最后一个一定是 0

思路:
遍历
从该数字开始向后遍历,记录下最小值,与左右两边进行比较
如果在遍历的过程中出现了 0 ,直接退出此次遍历,进行下一次的重复过程
出现 0 退出的原因:
如果出现了0 ,则一定是该字符串中最小的一个,不可能同时大于左右两边相邻的数字

例如
在这里插入图片描述
在字符串 2 4 3 中最小的数字是 2,任意数字都比左右两边的 1 、1 大,满足题意
在字符串 2 4 3 1 中最小的是 1,但是 1 和左边相邻的数字 1 相等,所以不满足

CODE:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
typedef long long LL;
using namespace std;
//#define memset(a,n) memset(a,n,sizeof(a))
#define INF 0x3f3f3f3f

int main()
{
    int t,k,flag;
    int a[15],sum;
    scanf("%d",&t);

    while(t--)
    {
        sum=0;
        scanf("%d",&k);
        for(int i=0;i<12;i++)
            scanf("%d",&a[i]);

        int pos,minn;
        for(int i=1;i<12;i++){

            pos=i-1;
            minn=a[i];  
            flag=0;

            for(int j=i;j<11;j++){
                if(a[j]==0){ // 出现0 直接退出
                    flag=1;
                    break;
                }

                if(a[j]<minn)  // 记录最小值
                    minn=a[j];
                if(minn>a[j+1]&&minn>a[pos]) // 大于两边
                    sum++;
            }

            if(flag==1)
                continue;
        }

        printf("%d %d\n",k,sum);
    }
}

3、 Happy Happy Prime Prime

RILEY VASHTEE: [reading from display] Find the next number in the sequence:
               313 331 367 …? What?
THE DOCTOR:  379.
MARTHA JONES: What?
THE DOCTOR: It’s a sequence of happy primes — 379.
MARTHA JONES: Happy what?
THE DOCTOR: Any number that reduces to one when you take the sum of the square of
its digits and continue iterating it until it yields 1 is a happy number. Any number that
doesn’t, isn’t. A happy prime is both happy and prime.
THE DOCTOR: I dunno, talk about dumbing down. Don’t they teach recreational mathematics
anymore?

The number 7 is certainly prime. But is it happy?
7 → 72 = 4949 → 42 + 92 = 9797 → 92 + 72 = 130130 → 12 + 32 = 1010 → 12 + 02 = 1

It is happy ?. As it happens, 7 is the smallest happy prime. Please note that for the purposes of
this problem, 1 is not prime.
For this problem you will write a program to determine if a number is a happy prime.

Input
The first line of input contains a single integer P, (1 ≤ P ≤ 1000), which is the number of data sets
that follow. Each data set should be processed identically and independently.
Each data set consists of a single line of input. It contains the data set number, K, followed by the
happy prime candidate, m, (1 ≤ m ≤ 10000).

Output
For each data set there is a single line of output. The single output line consists of the data set number,
K, followed by a single space followed by the candidate, m, followed by a single space, followed by ‘YES’
or ‘NO’, indicating whether m is a happy prime.

Sample Input
4
1 1
2 7
3 383
4 1000

Sample Output
1 1 NO
2 7 YES
3 383 YES
4 1000 NO

题意:
找快乐素数,需要满足两个条件
1、是素数
2、需要经过类似以下的过程,最后变成 1
7 → 72 = 4949 → 42 + 92 = 9797 → 92 + 72 = 130130 → 12 + 32 = 1010 → 12 + 02 = 1
图1

思路:
首先已知题目说7 是最小的快乐素数,小于 7都输出 NO;
其次判断是否为素数;
最后进行图1过程,限定进行分解的次数 1000 次,如果大于 1000 ,则说明不是快乐素数

CODE:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
typedef long long LL;
using namespace std;
//#define memset(a,n) memset(a,n,sizeof(a))
#define INF 0x3f3f3f3f

// 这里我用的最简单的素数判断,可以选择素数筛选
int Prime(int n)
{
    for(int i=2;i<=sqrt(n);i++)
        if(n%i==0)
            return 0;
    return 1;
}

LL cnt=0;
int Judge(int m)
{
    int n;
    int sum=0;
    while(m)
    {
        n=m%10;
        m/=10;
        sum+=pow(n,2);
    }
    cnt++;
    if(sum==1)
        return 1;
    if(cnt==1000)
        return 0;
    Judge(sum);
}

int main()
{
    int t,k,m;
    int flag;
    LL ans;
    scanf("%d",&t);
    while(t--)
    {
        cnt=0; // 这个地方卡了我两个小时,第一次wrong之后,就以为是规律题,然后就各种找规律,阿西吧
        scanf("%d %d",&k,&m);
        if(m<7){
            printf("%d %d ",k,m);
            printf("NO\n");
            continue;
        }

        flag=Prime(m);  // 判断素数
        if(flag==0){
            printf("%d %d ",k,m);
            printf("NO\n");
            continue;
        }

        flag=Judge(m);
        if(flag==1){
            printf("%d %d ",k,m);
            printf("YES\n");
            continue;
        }

        printf("%d %d ",k,m);
        printf("NO\n");

    }
}

**

4、A Rational Sequence

**
An infinite full binary tree labeled by positive rational numbers is defined by:
The label of the root is 1/1.
• The left child of label p/q is p/(p+q).
• The right child oflabel p/q is (p+q)/q.

The top of the tree is shown in the following figure:
在这里插入图片描述
A rational sequence is defined by doing a level order (breadth first) traversal of the tree (indicated
by the light dashed line). So that:
F(1) = 1/1, F(2) = 1/2, F(3) = 2/1, F(4) = 1/3, F(5) = 3/2, F(6) = 2/3, . . .

Write a program which takes as input a rational number, p/q, in lowest terms and finds the next
rational number in the sequence.
That is, if F(n) = p/q, then the result is F(n + 1).

Input
The first line of input contains a single integer P, (1 ≤ P ≤ 1000), which is the number of data sets
that follow. Each data set should be processed identically and independently.
Each data set consists of a single line of input. It contains the data set number, K, which is then
followed by a space, then the numerator of the fraction, p, followed immediately by a fonward slash (/),
followed immediately by the denominator of the fraction, q. Both p and q will be relatively prime and
0 ≤ p, q ≤ 2147483647.

Output
For each data set there is a single line of output. It contains the data set number, K, followed by a
single space which is then followed by the numerator of the fraction, followed immediately by a forward
slash (‘/’) followed immediately by the denominator of the fraction. Inputs will be chosen such that
neither the numerator nor the denominator will overflow a 32-bit integer.

Sample Input
5
1 1/1
2 1/3
3 5/2
4 2178309/1346269
5 1/10000000

Sample Output
1 1/2
2 3/2
3 2/5
4 1346269/1860498
5 10000000/9999999

题意:
看那个图就能明白了

The left child of label p/q is p/(p+q). 左子树等于 p/(p+q)
The right child oflabel p/q is (p+q)/q. 右子树等于 (p+q)/q

原本做个一个和这个题目类似的,第四题
此题的意思是:
知道 p/q ,求该节点的下一个节点数
可以分几种情况考虑:
1、如果是 1/1 ,直接写出 1/2
2、如果满足:
p=1,代表数的最左边,推出其父亲节点,根据公式求右子树
q=1,代表树的最右边,其下一个位置是 1/ p+1

3、如果处于对称位置的左边,一定满足 q=2(画一下图就明白咯)
 那么下一个值一定是与该值对称的
 
4、如果 p<q :(左子树)
则根据公式推出其父亲节点,然后再找其父亲节点的右子数

5、如果 p>q :(右子树)

	    (这个就需要仔细想想怎么推出来的,但不是我想出来的)
	      首先一直找其父亲节点,直到遇见一个 p<q的节点A,记录找寻的次数 cnt
	      然后找A的兄弟B,顺着B的左子树找 cnt 次,根据公式记录下每一个数值
	      分析:
	      为什么要找到一个 p<q 的节点A,因为已知 p<q 的节点算法,就可以求出下一个位置

CODE:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
typedef long long LL;
using namespace std;
//#define memset(a,n) memset(a,n,sizeof(a))
#define INF 0x3f3f3f3f

int path[1000];
LL cnt=0;
int k;


int main()
{
    int t;
    LL p,q,a,b,c;
    scanf("%d",&t);
    while(t--)
    {
        cnt=0;
        memset(path,0,sizeof(path));
        scanf("%d",&k);
        scanf("%lld/%lld",&q,&p);

        if(q==p&&q==1){
            printf("%d ",k);
            printf("1/2\n");
            continue;
        }

        if(q==1){
            a=p-q;
            printf("%d %lld/%lld\n",k,p,a);
            continue;
        }

        if(p==1){
            q+=1;
            printf("%d %lld/%lld\n",k,1,q);
            continue;
        }

        if(q<p){
            a=p-q;
            printf("%d %lld/%lld\n",k,p,a);
            continue;
        }

        if(p==2){
            printf("%d %lld/%lld\n",k,p,q);
            continue;
        }

        int sum=0;
        while(1)
        {
            if(q<p)
                break;
            q-=p;
            sum++;
        }
        
        a=p-q;
        // 这是利用循环一直找下来
        for(int i=0;i<sum;i++)
        {
            b=a+p;
            a=b;
        }
        
        /*   也可以这样
        a=p-q;
        b=a+p*sum;
        printf("%d %lld/%lld\n",k,p,b);
        比如
        7/3  结果是 3/8
        往上找依次是: 4/3  1/3(A) ,cnt = 2
        B: 3/2   ->   3/8
        只是分母发生了改变, 8=2+3*2  ( 3 代表的是 p)
        */

        printf("%d %lld/%lld\n",k,p,a);
    }
}

5、 Growing Rectangular Spiral

A growing rectangular spiral is a connected sequence of straightline
segments starting at the origin. The first segment goes right
(positive x direction). The next segment goes up (positive y direction).
The next segment goes left (negative x direction). The
next segment goes down (negative y direction) and the sequence
of directions repeats. Each segment has integer length and each
segment is at least one unit longer than the previous segment. In
the spiral on the right, the segment lengths are 1, 2, 4, 6, 7, 9,
11, 12, 15, 20.

在这里插入图片描述
Write a program to determine the shortest growing rectangular
spiral (in total length) that ends at a given integer point (x, y)
in the first quadrant or determine that there is no such spiral.

Input
The first line of input contains a single integer P, (1 ≤ P ≤ 1000), which is the number of data sets
that follow. Each data set should be processed identically and independently.
Each data set consists of a single line of input consisting of three space separated decimal integers.
The first integer is the data set number. The next two integers are the x and y coordinates of the
desired end point (1 ≤ x ≤ 10000, 1 ≤ y ≤ 10000).

Output
For each data set there is a single line of output. If there is no spiral solution, the line consists of the
data set number, a single space and ‘NO PATH’ (without the quotes). If there is a solution, the line
consists of the data set number, a single space, the number of segments in the solution, a single space,
followed by the lengths of the segments in order, separated by single spaces. The input data will be
chosen so that no path requires more than 22 segments.

Sample Input
3
1 1 1
2 3 5
3 8 4

Sample Output
1 NO PATH
2 2 3 5
3 6 1 2 3 9 10 11

题意:
看上述图片
给定结束点(x,y),通过以下过程到达
(1)、向左移动        (2)、向上移动
(3)、向右移动        (4)、向下移动
重复以上过程
需要满足每次移动的路径长度比上一次的大

给定结束点(x,y),问有没有上述的方法到达该点并且总路径最短
然后求最短时的转弯次数及每段路径的长度

思路:

由于需要求最少的转弯次数,那么如果可以通过(1)、(2)直达的就可以直达
否则只能通过六步最少   (1)(2)(3)(4)(1)(2)
限制一下每次的路径长度就好(每次都比上一次的大)
总路径最短的话前三步是 1 2 3 
为后三步留出可能

分三种情况讨论:
(1)、如果 x == y 或者 y < 2 的时候是没有路径的,不满足每次都比上一次的路经长
    y< 2的时,由于第二步的时候是2,那么最后一步的时候不可能大于第四步
    第四步是向下  2+m
    第六步是向上  y+m  (m是y轴以下走的单次路径长度)
  
(2)、如果 x< y的话,最短的转弯次数就是两步到达
先向左再向上,路径长度就是x,y坐标

(3)、如果 x > y 的话
假设y轴一下走的路径长度为 m
前三步是 1 2 3
第四步是 m + 2
第五步是 p=(3-1)+ x = x+2
第六步是 m + y
满足路径递增的条件是:
m+2 < p < m +y
如果 (m+2)+1 还是小于m+y的
那么就可以第四步走 (m+1)+2 第六步走 (m+1)+y
如果不满足,则输出 NO PATH

CODE:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
typedef long long LL;
using namespace std;
#define memset(a,n) memset(a,n,sizeof(a))
#define INF 0x3f3f3f3f

int main()
{
    int t,k,x,y;
    cin>>t;
    while(t--)
    {
        cin>>k>>x>>y;
        if(x==y||y<=2){
            cout<<k<<" NO PATH"<<endl;
            continue;
        }

        if(x<y){
            cout<<k<<' '<<2<<' '<<x<<' '<<y<<endl;
            continue;
        }

        int p,q;
        p=x+2;

        int xx=p-y,yy=p-2;
        if(xx+1<yy){
            int x1=xx+1+2;
            int y1=xx+1+y;

            cout<<k<<' '<<6<<' '<<1<<' '<<2<<' '<<3<<' '<<x1<<' '<<p<<' '<<y1<<endl;
        }
        else{
            cout<<k<<" NO PATH"<<endl;
        }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值