NCST 2018-2019秋季学期个人排位赛(一)

本文详细解析了NCST2018-2019秋季学期个人排位赛的四道题目,包括PUBG典型搜索问题、字符频率统计、数学函数计算精度控制以及排列组合去重算法,提供了完整的代码实现和技巧说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

NCST 2018-2019秋季学期个人排位赛(一)

A : PUBG

典型搜索,保存初始结束位置就行

#include<cstdio>
int maze[105][105];
int book[105][105];
int dir[4][2]={0,1,1,0,0,-1,-1,0};
int minn=0x3f3f3f3f;
int sx,sy,ex,ey,n;

void dfs(int x,int y,int step)
{
    if(x==ex&&y==ey)
    {
        if(step<minn)
            minn=step;
        return;
    }
    for(int k=0;k<4;++k)
    {
        int tx=x+dir[k][0];
        int ty=y+dir[k][1];
        if(tx<1||tx>n||ty<1||ty>n)
            continue;
        if(maze[tx][ty]==1||book[tx][ty])
            continue;
        book[tx][ty]=1;
        dfs(tx,ty,step+1);
        book[tx][ty]=0;
    }
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
        {
            scanf("%d",&maze[i][j]);
            if(maze[i][j]==3)
            {
                sx=i;sy=j;
            }
            if(maze[i][j]==4)
            {
                ex=i;ey=j;
            }
        }
    book[sx][sy]=1;
    dfs(sx,sy,0);
    printf("%d\n",minn);
    return 0;
}

B : (._.)的爱好

emmmm

#include<cstdio>
#include<algorithm>
#include<string.h>
using namespace std;
char s[55];
int a[27];
bool cmp(int x,int y)
{
    return x>y;
}
int main()
{
    scanf("%s",s);
    for(int i=0;i<strlen(s);++i)
        ++a[s[i]-'a'];
    sort(a,a+26,cmp);
    printf("%d",a[0]);
    return 0;
}

C : Math Function

#include<cstdio>
#include<algorithm>
int main()
{
    int m,n,x;
    scanf("%d",&m);
    while(m--)
    {
        scanf("%d %d",&n,&x);
        printf("%.*f\n",x,pow(n,3.1415926));   //控制精度
    }
    return 0;
}

D : 学姐的神秘卡片

大坑,这就是没有积累的坑,自己还在搜想为啥有重复,别人已经ac了TAT

#include<cstdio>
#include<set>
using namespace std;
int ans[15];	//获取的答案
int book[15]={0};
int arr[5];
set<int> s;	//干脆就用个set去重
void dfs(int num)
{
    if(num==4)
    {
        int x=ans[0]*1000+ans[1]*100+ans[2]*10+ans[3];
        s.insert(x);
        return;
    }
    for(int j=0;j<4;++j)
    {
        if(book[arr[j]]!=0)
        {
            ans[num]=arr[j];
            --book[arr[j]];
            dfs(num+1);
            ++book[arr[j]];
        }
    }
}
int main()
{
    for(int i=0;i<4;++i)
    {
        scanf("%d",&arr[i]);
        ++book[arr[i]];		
        //想有重复就++了,不过这样也造成了排列重复,比如1 1 2 3,
        //会把两个1当作不同的1,所以有重复(可能是这样)
    }
    dfs(0);
    for(set<int>::iterator it=s.begin();it!=s.end();++it)
        printf("%d ",*it);
    printf("\n");
    return 0;
}

STL里已经提供了计算排列的函数分别是next_permutation和prev_permutation ,前者产生当前的下一个排列,后者产生前一个排列,排序按字典序

template<class BidirectionalIterator>
   bool next_permutation(
      BidirectionalIterator _First, 
      BidirectionalIterator _Last
   );

这多简单

#include<cstdio>
#include<algorithm>
using namespace std;
int main()
{
    int num[4];
    for(int i=0;i<4;i++)
        scanf("%d",&num[i]);
    sort(num,num+4);	//输入的保证
    do
    {
        printf("%d%d%d%d\n",num[0],num[1],num[2],num[3]);
    } while(next_permutation(num,num+4));
    return 0;
}

不用set的去重,直接在赋值判断那里判断前一个和后一个是否相等就可以,因为给定的数组是要按照顺序的,所以一样的一定在一起

#include<cstdio>
int ans[15];
int book[15];
int arr[5];
void dfs(int num)
{
    if(num==4)
    {
        for(int i=0;i<4;++i)
            printf("%d",ans[i]);
        printf(" ");
        return;
    }
    for(int j=0;j<4;++j)
    {
        if(book[arr[j]]!=0&&(!j||arr[j]!=arr[j-1]))//!j是j=0时防止数组越界
        {
            ans[num]=arr[j];
            --book[arr[j]];
            dfs(num+1);
            ++book[arr[j]];
        }
    }
}
int main()
{
    for(int i=0;i<4;++i)
    {
        scanf("%d",&arr[i]);
        ++book[arr[i]];
    }
    dfs(0);
    printf("\n");
    return 0;
}

E : 跳蚤市场

递归模拟

#include<cstdio>
int start=2,x_tot=5,tot=10;//开始的书,总共5个学姐,10次新生
int num=0;
void fun(int cur,int a,int b)
{
    if(cur==0&&a==x_tot&&b==tot)
    {
        ++num;
        return;
    }
    else
    {
        if(cur>0&&a<x_tot)	//学姐给书
            fun(cur*2,a+1,b);
        if(cur>0&&now_tot<tot)	//送新生书
            fun(cur-1,a,b+1);
    }
}
int main()
{
    fun(start,0,0);
    printf("%d\n",num);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值