2017上海金马五校程序设计竞赛部分题解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/moonlighttlj/article/details/72853929

Problem A : STEED Cards


 (Out of Contest)

Time Limit: 1 s

Description

Corn does not participate the STEED contest, but he is interested in the word "STEED". So, Corn writes all permutations of the word "STEED" on different cards and gets 60 cards finally.

Corn sorts these cards in lexicographical order, and marks them from 1 to 60.

Now, Corn gives you a integer N (1 ≤ N ≤ 60), could you tell him the word on the Nth card?

 

Input

There are multiple test cases (no more than 60).
For each test case, there is one integer N (1 ≤ N ≤ 60) in a line.

 

Output

For each test case, you should output one line with the word on the Nth card.

 

Sample Input

1
2
3
4
47
48
49

 

Sample Output

DEEST
DEETS
DESET
DESTE
STEDE
STEED
TDEES

 


Author: Corn

题意:Corn将"STEED"按照字典序排列并且给它们编号从1到60,现在给你一个数字N,要求出编号为N的字符串

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
int main()
{
    int i=-1,j;
    char a[]={'D','E','E','S','T'};
    string s[70];
    do
    {
        i++;
        for(j=0;j<5;j++)
            s[i]+=a[j];
    }while(next_permutation(a,a+5));
    int n;
    while(~scanf("%d",&n))
    {
        cout<<s[n-1]<<endl;
    }
    return 0;
}

Problem B : Sailing


 (Out of Contest)

Time Limit: 1 s

Description

Handoku is sailing on a lake at the North Pole. The lake can be considered as a two-dimensional square plane containing N× N blocks, which is shown in the form of string containing '*' and '#' on the map.

  • * : a normal block;
  • # : a block containing pack ice.


Handoku is at (1, 1) initially, and his destination is (NN). He can only move to one of the four adjacent blocks. Sailing around pack ice is dangerous and stressful, so he needs power to remain vigilant. That means if he moves from a '*' block to a '#' block or moves from a '#' block to any another block, he needs to consume 1 unit power. In other cases, he can enjoy the scene on his boat without consuming any power.

Now Handoku wants to know how many units power will be consumed at least during his sailing on the lake.

 

Input

There are several test cases (no more than 20).
For each test case, the first line contains a single integer N (3 ≤ N ≤ 50), denoting the size of the lake. For the following Nlines, each line contains a N-length string consisting of '*' and '#', denoting the map of the lake.

 

Output

For each test case, output exactly one line containing an integer denoting the answer of the question above.

 

Sample Input

3
**#
**#
*#*
3
##*
#*#
###
4
**##
#**#
##**
###*

 

Sample Output

2
4
0

 


Author: handoku

题意:Handoku正在北极的一个湖上行驶,湖可以被看成一个二维的方形包含N*N个方格,方格中的数据以'*'和'#'呈现在图上
*:代表一个正常的方格
#:代表一个包含冰块的方格
Handoku起初在(1,1)位置并且他的目标是(N,N),他只有四个方向可以移动,在包含冰块的方格附近移动是危险又有压力的所以他需要能量去保持机警,这意味着如果他从'*'到'#'或是从'#'到任意一个方格,都需要花费一单元的能量.在其他情况下不用花费任何能量.现在Handoku想知道他在这次航行中至少要花费多少?

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
#define INF 0x3f3f3f3f
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//四个方向
int n,a[52][52],vis[52][52];
struct node
{
    int x,y;
    int time;
    friend bool operator<(node a,node b)//优先队列优先从小到大
    {
        return a.time>b.time;
    }
}pre,now;
void bfs()
{
    priority_queue<node>q;
    pre.x=1;
    pre.y=1;
    pre.time=0;
    q.push(pre);
    while(!q.empty())
    {
        now=q.top();
        q.pop();
        if(now.x==n&&now.y==n)
        {
            printf("%d\n",now.time);
            break;
        }
        for(int i=0;i<4;i++)
        {
            pre.x=now.x+dir[i][0];
            pre.y=now.y+dir[i][1];
            if(pre.x>=1&&pre.x<=n&&pre.y>=1&&pre.y<=n)
            {
                if(a[pre.x][pre.y]=='#'||a[now.x][now.y]=='#')
                   pre.time=now.time+1;//如果他从'*'到'#'或是从'#'到任意一个方格,都需要花费一单位的能量
                else
                   pre.time=now.time;//在其他情况下不用花费任何能量
                if(vis[pre.x][pre.y]>pre.time)
                {//如果再次走过当前点比当前点保存的时间短就更新并入队,而不是说走过一个点就标记不能再走了
                     vis[pre.x][pre.y]=pre.time;
                     q.push(pre);
                }
            }
        }
    }
}
int main()
{
    while(~scanf("%d",&n))
    {
        int i,j;
        for(i=1;i<=n;i++)
        {
            getchar();//这个地方不要忘了加
            for(j=1;j<=n;j++)
            scanf("%c",&a[i][j]);
        }
        memset(vis,INF,sizeof(vis));//用来存放方格中到达当前点所消耗的最小能量
        bfs();
    }
    return 0;
}

Problem C : Count the Number


 (Out of Contest)

Time Limit: 3 s

Description

Given n numbers, your task is to insert '+' or '-' in front of each number to construct expressions. Note that the position of numbers can be also changed.

You can calculate a result for each expression. Please count the number of distinct results and output it.

 

Input

There are several cases.
For each test case, the first line contains an integer n (1 ≤ n ≤ 20), and the second line contains n integers a1,a2, ... ,an(-1,000,000,000 ≤ ai ≤ 1,000,000,000).

 

Output

For each test case, output one line with the number of distinct results.

 

Sample Input

2
1 2
3
1 3 5

 

Sample Output

4
8

 


Author: Sherry

题意:被给n个数,你的任务是在每个数的前面加'+'或 '-',注意的是数字的位置可以被改变.对于每种表达你可以计算出一个结果,
请计算不同结果的个数并将其输出.

这个题其实我做的时候是理解题意的,可是做着做着就和题意不太符合了。不过有趣的是就一遍AC了,也算是歪打正着了。

下面把我一不小心AC的代码贴出来(其实能AC也是有一定原因的:因为总的数和是一样的我这样算是把正的数之和都求出来了,

只要保证正的数之和不重复,答案也就是对的了)

思路:这道题我没有用搜索,按照我上面简略介绍的而是用到了二进制,原因不难得出吧。而且我自己觉得这样比较方便。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
int aa[21],x[2000005];//x数组用于标记数字是否出现过
void f(int n)//将十进制转化为二进制数字
{
    int i=0;
    while(n!=0)
    {
        aa[i++]=n%2;
        n/=2;
    }
}
int main()
{
    int n,a[25],k,b[21]={0},s[25]={0},l;
    b[0]=1,s[0]=1;
    for(k=1;k<20;k++)
    {
        b[k]=b[k-1]*2;//b数组存放2的次幂
        s[k]=s[k-1]+b[k];//s数组存放前n项2的次幂之和
    }
    while(~scanf("%d",&n))
    {
        int i,j,c=0;
        memset(x,0,sizeof(x));
        for(i=0;i<n;i++)
            scanf("%d",&a[i]);
        for(i=0;i<=s[n-1];i++)
        {
            l=0;
            memset(aa,0,sizeof(aa));//每次初始化
            f(i);//得到当前数字的二进制,得到各种'+'或'-'插入的可能的结果
            for(j=0;j<n;j++)
               l+=aa[j]*a[j];
            if(x[l]==0)
            {
                x[l]=1;
                c++;//存放最后结果
            }
        }
        printf("%d\n",c);
    }
    return 0;
}
所以这个二进制的作用明白了吧

Problem E : Find Palindrome


 (Out of Contest)

Time Limit: 1 s

Description

Given a string S, which consists of lowercase characters, you need to find the longest palindromic sub-string.

A sub-string of a string S  is another string S'  that occurs "in" S. For example, "abst" is a sub-string of "abaabsta". A palindrome is a sequence of characters which reads the same backward as forward.

 

Input

There are several test cases.
Each test case consists of one line with a single string S (1 ≤ || ≤ 50).

 

Output

For each test case, output the length of the longest palindromic sub-string.

 

Sample Input

sasadasa
bxabx
zhuyuan

 

Sample Output

7
1
3

 


Author: Kenny

题意:求最大回文字串的长度

思路:我是按照求两个字符串的最大公共字串的方法来实现的,当然一个字符串的最大回文字串和两个字符串的最大公共字串是不一样的。只要再加一个判断条件就可以了(主要是因为位置原因,一个字符串的最大回文字串位置较于两个字符串的最大公共字串更死板一些,所以在求两个字符串的最大公共字串长度时再加一个判断条件就行了

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
int main()
{
    char a[100],b[100];
    int dp[100][100];
    while(gets(a))
    {
        int i,j,len,maxn=0;
        len=strlen(a);
        for(i=0;i<len;i++)
          b[i]=a[len-1-i];//将a字符串反过来
        memset(dp,0,sizeof(dp));
        for(i=1;i<=len;i++)
            for(j=1;j<=len;j++)
            {
                if(a[i-1]==b[j-1])
                    dp[i][j]=dp[i-1][j-1]+1;
                if(dp[i][j]>maxn&&len-i==j-dp[i][j]&&len-(i-dp[i][j])-1==j-1)//注意这里的判断条件就是我所强调的
                    maxn=dp[i][j];
            }
        printf("%d\n",maxn);
    }
    return 0;
}

Problem I : Frog's Jumping


 (Out of Contest)

Time Limit: 1 s

Description

There are n lotus leaves floating like a ring on the lake, which are numbered 0, 1, ..., n-1 respectively. The leaf 0 and n-1 are adjacent.

The frog king wants to play a jumping game. He stands at the leaf 0 initially. For each move, he jumps k (0 < k < n) steps forward. More specifically, if he is standing at the leaf x, the next position will be the leaf (x + k) % n.

After n jumps, he wants to go through all leaves on the lake and go back to the leaf 0 finally. He can not figure out how many different k can be chosen to finish the game, so he asks you for help.
 

 

Input

There are several test cases (no more than 25).
For each test case, there is a single line containing an integer n (3 ≤ n ≤ 1,000,000), denoting the number of lotus leaves.

 

Output

For each test case, output exactly one line containing an integer denoting the answer of the question above.

 

Sample Input

4
5

 

Sample Output

2
4

 


Author: handoku

题意:n个荷叶像一个环一样的立在水中,分别编号为0,1,,,,n-1。0和n-1是相邻的。青蛙国王想要玩一个游戏,它最开始在0的位置,每次移动,他会向前跳k步(0<k<n),特别地,如若它站在编号为x的荷叶上,那么再跳一次之后它会出现在编号为(x + k) % n的位置。跳了n次之后,它想经过湖中所有的叶子并且最后回到0位置。它想知道有几个不同的k能满足条件?

思路:我开始只是想用模拟试试结果还被周围的人嘲笑了,当然这次尝试以失败告终。

因为数据太大,后来是用找规律做的。只要是n的约数的倍数都不满足条件,去掉这些都是满足条件的了。证明可以自行尝试,这里就只说结论了。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
int a[1000005];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        int i,j=0,m=n-1;//
        memset(a,0,sizeof(a));
        for(i=2;i<n;i++)
        {
            if(n%i==0)//满足是约数
            {
                for(j=1;j*i<n;j++)
                if(a[j*i]==0)//约数的倍数
                {
                    a[j*i]=1;//因为约数的倍数可能会有重复,所以用到标记数组
                    m--;
                }
            }
        }
        printf("%d\n",m);
    }
    return 0;
}

Problem O : An Easy Problem


 (Out of Contest)

Time Limit: 2 s

Description

Zhu Ge is a very clever boy. One day, he discovered 2*n numbers. He wanted to divide them into n groups, each group contains 2 integers, and minimize the sum of the absolute value of the difference of the numbers in each group.

The problem is too difficult to Zhu Ge, so he turned to you. He hopes you can calculate the minimum of the sum of absolute value of the difference among different division strategies.

 

Input

There are several test cases.
For each test case, there is an integer n (n < 10,000) at the first line. The second line contains 2*n integers. The input ends up with EOF.

 

Output

For each test case, output the minimum of sum.

 

Sample Input

3
10 3 4 5 1 6
5
64 5 63 63 23 63 54 64 3 54

 

Sample Output

7
42

 


Author: Kuang

题意:诸葛是一个聪明的男孩,一天他发现了2*n个数字,他想把他们分成n组,每组包含两个数字。他想求出每组两个数差的绝对值之和的最小值。题目中给的只是n的值,数组注意不要开小了。数据类型没有给,是long long int类型的。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
int main()
{
    int n;
    long long int a[30005];
    while(~scanf("%d",&n))
    {
        int i;
        for(i=0;i<2*n;i++)
          scanf("%lld",&a[i]);
        sort(a,a+2*n);
        long long int s=0;
        for(i=0;i<2*n;i+=2)
            s+=a[i+1]-a[i];
        printf("%lld\n",s);
    }
    return 0;
}









阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页