NYIST-2019省赛训练个人积分赛第一场

A - 打牌

HDU 1584

Problem Description
蜘蛛牌是windows xp操作系统自带的一款纸牌游戏,游戏规则是这样的:只能将牌拖到比她大一的牌上面(A最小,K最大),如果拖动的牌上有按顺序排好的牌时,那么这些牌也跟着一起移动,游戏的目的是将所有的牌按同一花色从小到大排好,为了简单起见,我们的游戏只有同一花色的10张牌,从A到10,且随机的在一行上展开,编号从1到10,把第i号上的牌移到第j号牌上,移动距离为abs(i-j),现在你要做的是求出完成游戏的最小移动距离。

Input
第一个输入数据是T,表示数据的组数。
每组数据有一行,10个输入数据,数据的范围是[1,10],分别表示A到10,我们保证每组数据都是合法的。

Output
对应每组数据输出最小移动距离。

Sample Input
1
1 2 3 4 5 6 7 8 9 10

Sample Output
9

这道题在比赛的时候感觉到是搜索了,奈何我的搜索学的宛如一个智障。。。。。
因为题中说的很明白1只能叠加到2上,2只能叠加到3上… … …以此类推,所以我们搜索的是叠加的顺序,比如简单一点3个数1 2 3:我们深度搜索的是,1先叠加到2上然后2再叠加到3上,还是,2先叠加到3上然后1再叠加到3上;再搜索的时候注意剪枝

#include
#include
#include
using namespace std;
int a[15],vis[15];
int sum;
void dfs(int cnt,int ans)
{
    if(cnt==9)
        sum=min(ans,sum);
    if(ans>sum)
        return ;
    for(int i=1;i<10;i++)
    {
        if(!vis[i])
        {
            vis[i]=1;
            for(int j=i+1;j<=10;j++)
            {
                if(!vis[j])
                {
                    dfs(cnt+1,ans+abs(a[i]-a[j]));
                    break;
                }
            }
            vis[i]=0;
        }
    }
}
int main()
{
    int T,x;
    scanf("%d",&T);
    while(T--)
    {
        memset(vis,0,sizeof(vis));
        memset(a,0,sizeof(a));
        for(int i=1;i<=10;i++)
        {
            scanf("%d",&x);
            a[x]=i;
        }
        sum=0x3f3f3f3f;
        dfs(0,0);
        printf("%d\n",sum);
    }
    return 0;
}

B Good Numbers

HDU 4722

具体题解看单发博客
B题
·
·
·

盒子嵌套

HDU 1110

就不复制英文题意了

大概题意是给你两个长方形的长宽a,b,x,y,问你第二个长方形能不能放进第一个长方形(坑点为不能完完全全的覆盖,只要有一点没有碰到就行)
NYIST-2019省赛训练个人积分赛第一场_第1张图片
也就是比较h和a的大小,当h

#include
#include
#include
#include
using namespace std;
int f(double a,double b,double x,double y)
{
    double k=sqrt(x*x+y*y);
    double j=acos(y/k)-acos(b/k);
    double h=y*sin(j)+x*cos(j);
    if(h<a)
        return 1;
    return 0;
}
int main()
{
    double a,b,x,y;
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lf %lf %lf %lf",&a,&b,&x,&y);
        if(a<b)
            swap(a,b);
        if(x<y)
            swap(x,y);
        if(a>x&&b>y)
        {
            printf("Escape is possible.\n");
            continue;
        }
        else if(y>b||a*b<=x*y)
        {
            printf("Box cannot be dropped.\n");
            continue;
        }
        else
        {
            if(f(a,b,x,y))
                printf("Escape is possible.\n");
            else
                printf("Box cannot be dropped.\n");
        }
    }
    return 0;
}

D - 防ak

HDU 1535

题目太长就不复制了(比赛的时候,英语真的是个硬伤,看样例猜到了是最短路,奈何英语是个硬伤,没看出具体的题意。。。。很难受)
大概题意:n个点m条有向边,每条边有一个权值,问你从点1到其他所有点,再从其他所有点返回到点1所要花费的最小值

其实就是从1点跑一个最短路,然后反向存边,再跑一遍最短路

#include
#include
#include
#include
using namespace std;
int tot;
int f[1000005],book[1000005];
struct node
{
    int u,v,w;
};
node a[1000005];
struct node1
{
    int v,w,nex;
};
node1 e[1000005];
long long dis[1000005];
const long long inf=9223372036854775807;

void init(int n)//所需变量初始化
{
    tot=0;
    for(int i=0;i<=n+2;i++)
    {
        dis[i]=inf;
        book[i]=0;
        f[i]=-1;
    }
}
void add(int u,int v,int w)//邻接表存边
{
    e[tot].v=v;
    e[tot].w=w;
    e[tot].nex=f[u];
    f[u]=tot++;
}
void spfa()//最短路
{
    queue<int>q;
    q.push(1);
    book[1]=1;
    dis[1]=0;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(int i=f[u]; i!=-1; i=e[i].nex)
        {
            int v=e[i].v;
            if(dis[v]>dis[u]+e[i].w)
            {
                dis[v]=dis[u]+e[i].w;
                if(book[v]==0)
                {
                    q.push(v);
                    book[v]=1;
                }
            }
        }
        book[u]=0;
    }
}
int main()
{
    int n,m,T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d %d",&n,&m);
        init(n);
        for(int i=1; i<=m; i++)
        {
            scanf("%d %d %d",&a[i].u,&a[i].v,&a[i].w);
            add(a[i].u,a[i].v,a[i].w);
        }
        spfa();
        long long sum=0;
        for(int i=1;i<=n;i++)
            sum+=dis[i];
        init(n);
        for(int i=1;i<=m;i++)//反向存边
            add(a[i].v,a[i].u,a[i].w);
        spfa();
        for(int i=1;i<=n;i++)
            sum+=dis[i];
        printf("%lld\n",sum);
    }
    return 0;
}

·
·

E - 海戰

codeforces 729D

看不懂题意是真的伤。。。比赛完用百度翻译看题还是没搞懂题意是啥。。。。绝了。。。
大概题意:有1-n个格子,a艘船,每个船要占连续b个格子,已经确定有k个格子没有船,那么每次射击一个格子,最少要射击多少次一定能射击到一个船。

我们先算出来一共最多可以放cnt条船(记录一下每条船的位置),那么我们把这nun条船射击到只剩a-1条船,就一定射击到了一条船

#include
#include
#include
using namespace std;
char s[200005];
int ans[200005];
int main()
{
    int n,a,b,k;
    while(~scanf("%d %d %d %d",&n,&a,&b,&k))
    {
        memset(ans,0,sizeof(ans));
        int t=0,cnt=0;
        scanf("%s",s+1);
        for(int i=1;i<=n;i++)
        {
            if(s[i]=='1')
                t=0;
            else
                t++;
            if(t%b==0&&t!=0)
            {
                ans[cnt++]=i;
            }
        }
        printf("%d\n",cnt-a+1);
        for(int i=0;i<cnt-a+1;i++)
            printf("%d ",ans[i]);
        printf("\n");
    }
    return 0;
}

·
·

F - 你永遠下不贏老師

codeforces 630 R

题意:有一个n*n的方格,开始的时候每个格子都是空的,两个人轮流在方格纸中选一个格子涂上一个颜色,涂的每个格子和之前涂的格子不能有相同的边,问如果是你,当n不同的时候,选择先涂还是后涂可以赢

简单博弈,当n为奇数的时候,所能涂的格子是奇数,所以先涂,偶数的时候能涂的格子数是偶数,所以后涂

#include
#include
#include
using namespace std;
int main()
{
    long long n;
    while(~scanf("%lld",&n))
    {
        if(n%2)
            printf("1\n");
        else
            printf("2\n");
    }
    return 0;
}

·
·

G - 很麻煩的題

HDU 1250

题意就是:F(1) = 1, F(2) = 1, F(3) = 1,F(4) = 1, F(n>4) = F(n - 1) + F(n-2) + F(n-3) + F(n-4)
让你算第n个数

当时比赛的时候,电脑上没有java的编译器。。。然后我硬盒的用cb打了个java,结果就是不停的CE,反正最后A掉了。。。也是很绝望

import java.math.BigInteger;
import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        BigInteger a[] = new BigInteger[10005];
        BigInteger y = new BigInteger("1");
        a[1]=y;
        a[2]=y;
        a[3]=y;
        a[4]=y;
        for(int i=5;i<=10000;i++){
           BigInteger x = new BigInteger("0");
           x=x.add(a[i-1]);
           x=x.add(a[i-2]);
           x=x.add(a[i-3]);
           x=x.add(a[i-4]);
           a[i]=x;
        }
        while(in.hasNext()){
            int n=in.nextInt();
            System.out.println(a[n]);
        }
    }
}

·
·

H - Points in Segments

CodeForces - 1015A

大概题意:有一个1-n的数轴,m个区间【a,b】,每个区间覆盖了一个颜色,问最后在数轴上还有哪些点没有被覆盖

看了一下n,m的取值范围是100,然后就直接暴力模拟了

#include
#include
#include
using namespace std;
int a[1005];
int b[1005];
int main()
{
    int n,m;
    while(~scanf("%d %d",&n,&m))
    {
        memset(a,0,sizeof(a));
        int x,y;
        for(int i=1;i<=n;i++)
        {
            scanf("%d %d",&x,&y);
            for(int j=x;j<=y;j++)
                a[j]=1;
        }
        int sum=0;
        for(int i=1;i<=m;i++)
        {
            if(!a[i])
                b[sum++]=i;
        }
        printf("%d\n",sum);
        for(int i=0;i<sum;i++)
            printf("%d%c",b[i],i==sum-1?'\n':' ');
        if(sum==0)
            printf("\n");
    }
    return 0;
}

这场比赛打得我。。。内心很是绝望。。B题知道是数位dp没有的打出来,然而也没有记板子(再不记板子我是狗。。。。)后面的题基本都是板子题。。。英语太差。。。A题的深搜其实也很简单,但是没有写出来。。。。反正就是还是很菜。。。(哭唧唧)

你可能感兴趣的:(2019省赛集训个人和组队赛)