zoukankan      html  css  js  c++  java
  • 2018 HNUCM ACM集训队选拔第一场

    1.小c的倍数问题

    http://acm.hdu.edu.cn/showproblem.php?pid=6108

    分析:

    QQ图片20180706192115

    比赛的时候真的是各种想,结果发现自己是想多了。。。数论基础差得一批

    求有多少个因子的时候,不能直接1到q-1暴力去求,要sqrt(q-1),所以每次有%=0的时候,都是加2,因为我们算的是sqrt(q-1),注意如果i*i==q-1的时候,只加1

    这个自己一开始都没想通,对为什么要加2还感到奇怪。。。

    看来以后得多写数论了。。。

    code:

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int n;
            scanf("%d",&n);
            int sum=2;
            n--;
            for(int i=2;i<=sqrt(n);i++)
            {
                if(n%i==0&&i*i!=n)
                    sum+=2;
                if(n%i==0&&i*i==n)
                    sum++;
            }
            printf("%d
    ",sum);
        }
        return 0;
    }

    2.24点问题

    http://10.10.10.170/vjudge/contest/view.action?cid=6#problem/A

    A - 24

    Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

    Submit Status Practice FZU 2284

    Description

    有一天dark sil在玩24点,被杰哥看见了,杰哥就想到了这样一个问题:假设有N张卡片,上面写着1,2,3....N,是否可以用这些卡片组成24点呢?要求是只能使用加减乘除(整除),所有的卡片都必须用上,并且只能使用一次。如果可以组成24点,则输出"Yes",否则输出“No”.

    假设N等于5,那么存在1*2*(3+4+5)=24.

    Input

    包含多组测试数据,每组测试数据的第一行输入一个数字T,表示接下去输入T组数据。

    接下去T行,每一行输入一个N,意思如题目中所描述。

    T≤30,n≤100000

    Output

    对于每组数据,输出一行"Yes"或者“No”

    Sample Input

    2 3 4

    Sample Output

    No

    Yes

    分析:

    QQ图片20180706205827

    code:

    #include<stdio.h>
    int main()
    {
        int n,t;
        while(~scanf("%d",&t))
        {
            while(t--)
            {
                scanf("%d",&n);
                if(n>=4)
                {
                    printf("Yes
    ");
                }
                else
                {
                    printf("No
    ");
                }
            }
        }
    
        return 0;
    }

    3.迷宫寻宝(BFS)

    http://acm.hnucm.edu.cn/vjudge/contest/view.action?cid=6#problem/B

    第一次写bfs题。。。菜

    直接套bfs模板

    我们可以用一个队列来记录一些点,每一次都取出队首元素,然后对其进行4个方向的探索,如果当vis[fx][fy]!=0的时候,代表已经找到终点,此时就退出程序,输出次数就行。(vis[fx][fy]代表的是从起始点到终点一共移动的步数)

    #include<iostream>
    #include<queue>
    #include<string.h>
    #include<stdio.h>
    using namespace std;
    #define max_n 1005
    char a[max_n][max_n];//记录图形
    int vis[max_n][max_n];//记录点的使用情况
    int dir[4][2]={
    -1,0,//方向引导数组
    1,0,
    0,1,
    0,-1};
    struct point
    {
        int x,y;
    };
    struct point temp1,temp2;
    queue<point> Q;
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            int sx,sy,fx,fy;//起点和终点的坐标
           // memset(vis,0,sizeof(vis));
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                {
                    vis[i][j]=0;
                }
            }
            for(int i=0;i<n;i++)
            {
                scanf("%s",a[i]);
            }
            for(int i=0;i<n;i++)//找到起点和终点
            {
                for(int j=0;j<n;j++)
                {
                    if(a[i][j]=='S')
                    {
                        sx=i;
                        sy=j;
                    }else if(a[i][j]=='E')
                    {
                        fx=i;
                        fy=j;
                    }
                }
            }
            while(!Q.empty())//队列清空
            {
                Q.pop();
            }
            vis[sx][sy]=1;
            temp1.x=sx;
            temp1.y=sy;
            Q.push(temp1);
            int flag=0;
            while(!Q.empty())
            {
                temp1=Q.front();
                Q.pop();
                for(int i=0;i<4;i++)
                {
                    temp2.x=temp1.x+dir[i][0];
                    temp2.y=temp1.y+dir[i][1];
                    if(temp2.x>=0&&temp2.y>=0&&temp2.x<n&&temp2.y<n&&!vis[temp2.x][temp2.y]&&a[temp2.x][temp2.y]!='#')
                    {
                        vis[temp2.x][temp2.y]=vis[temp1.x][temp1.y]+1;
                        Q.push(temp2);
                    }
                }
                if(vis[fx][fy]!=0)
                {
                    flag=1;
                    break;
                }
            }
            if(flag==1)
            {
                printf("%d ",vis[fx][fy]-1);
            }else
            {
                printf("-1 ");
            }
        }
        return 0;
    }

    4.RPG

    http://acm.hnucm.edu.cn/vjudge/contest/view.action?cid=6#problem/C

    C - RPG

    Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

    Submit Status Practice FZU 2286

    Description

    Simon最近迷上了一款RPG游戏,现在他要从坐标(0,0)沿着y轴跑到坐标(0,100),他每秒能跑1个单位长度。

    可是沿途的怪物可不会让他这么容易的就跑到,怪物会选择最优路径进行拦截,而且每个怪物跑的都比Simon快。

    当怪物和Simon在同一坐标的时候,就会爆发战斗。但是Simon强,无敌,战斗一开始就可以把怪物秒了(也就是说,战斗是不消耗时间的)。

    现在Simon想知道跑到目的地前他要和几只怪物战斗。(在目的地爆发的战斗也要计算在内)

    Input

    题目包含多组测试数据,每组测试数据第一行包含一个正整数n,表示怪物个数。

    接下来n行,每行三个整数x,y,v,表示怪物当前的坐标和移动速度(单位长度/秒)。

    n≤10^5,-1000<=x<=1000,-1000<=y<=1000,1<=v<=1000

    Output

    输出一个整数,表示战斗场数

    Sample Input

    3 0 0 5 0 200 1 0 201 1

    Sample Output

    2

    分析:

    脑洞题,只要所有怪兽能在100s内到达终点的话,就一定会遇到

    #include <iostream>
    #include <cstdio>
    #include <list>
    #include <stack>
    #include <queue>
    #include <cstdlib>
    #include <set>
    #include <map>
    #include <vector>
    #include <cstring>
    #include <string>
    #include <cmath>
    using namespace std;
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            double x,y,v;
            int sum=0;
            while(n--)
            {
                scanf("%lf %lf %lf",&x,&y,&v);
                if(sqrt(x*x+fabs(y-100)*fabs(y-100))*1.0/v<=100)
                    sum++;
            }
            printf("%d ",sum);
        }
        return 0;
    }

    5.给力的移动

    http://acm.hnucm.edu.cn/vjudge/contest/view.action?cid=6#problem/D

    D - 给力的移动

    Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

    Submit Status Practice FZU 2287

    Description

    你的弟弟给你安排了一个任务,他给了你1到N个数字的乱序排列,现在你想给你的弟弟秀一波操作,操作最少的次数把序列变成1到N的顺序排列,每次操作你可以选择序列中的一个数字并把它移动到序列的头部或尾部。

    Input

    包含多组测试数据。

    每组测试数据的第一行为正整数N,表示排列的长度。

    第二行为N个数字的乱序排列。

    n≤100000

    Output

    输出最少的操作次数

    Sample Input

    6 6 3 2 4 5 1

    Sample Output

    3

    分析:

    带限定条件的最长递增子序列问题(LIS问题)

    就问你间隔为1的最长递增子序列的长度是多少

    然后n减去LIS序列的长度,就是需要操作的次数

    ps:写过几道LIS的题目,比赛却没有想到,被自己蠢哭。。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<stdio.h>
    #define max_n 100005
    int max_f(int x,int y)
    {
        if(x>y)
            return x;
        else
            return y;
    }
    int dp[max_n];
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            memset(dp,0,sizeof(dp));
            int result=0;
            for(int i=0;i<n;i++)
            {
                int x;
                scanf("%d",&x);
                dp[x]=dp[x-1]+1;
                result=max_f(dp[x],result);
            }
            printf("%d ",n-result);
        }
        return 0;
    }
  • 相关阅读:
    Passion回来了
    VS.NET Addin在Design time获取控件值
    [过时的消息]VS2005 Shipped!
    为asp.net程序添加自定义配置区域
    Visual Studio .NET 2002 Service Pack 1 出来了
    Winform下通过控件名称来获取控件
    new blog, new life
    我的hotmail信箱容量变成2G了!
    first day in microsoft
    在client端通过java script调用Web Service
  • 原文地址:https://www.cnblogs.com/yinbiao/p/9275688.html
Copyright © 2011-2022 走看看